java反射

来源:互联网 发布:隐藏文件恢复软件 编辑:程序博客网 时间:2024/06/06 07:27

一、什么是反射

反射就相当于一面镜子,可以获取自身的信息。在java中,只要给定类名称,就能通过反射机制获取所有的信息。

二、哪里用到反射

有些时候,我们用过一些知识,但是并不知道它的专业术语是什么,在刚刚学jdbc时用过一行代码, Class.forName("com.mysql.jdbc.Driver.class").newInstance();但是那时候只知道那行代码是生成 驱动对象实例,并不知道它的具体含义。听了反射机制这节课后,才知道,原来这就是反射,现在很多开 框架都用到反射机制,hibernatestruts都是用反射机制实现的。 

三、优点和缺点

估计有人会问为什么不用new直接创建对象呢,反而用反射机制,那么麻烦的创建对象?其实这个问题我也是起初也考虑过,只不过明白了反射后才知道它可以减少代码的冗余,还有一个原因就是动态创建对象和静态创建对象的差别(动态创建对象会使代码更灵活)。尤其是在jdbc中,写那些语句的时候。本来我们会写很多的方法去取各个表的数据,但是有了反射后,只要写四个方法(增、删、改、查)就可以搞定。估计有些人会怀疑,但是看了下面的代码你就会明白我为什么这么说了。

1、首先数据库的有一个表,假设数据库名称为:blogsystem,里面的一个表名userinfo。如图:

2、创建对应的pojo类:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

package cn.netjava.pojo;

 

public class UserInfo {

private int id;

private String name;

private String pwd;

private int age;

 

@Override

public String toString() {

    return "UserInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + ", age="

            + age + "]";

}

public int getId() {

    return id;

}

public void setId(int id) {

    this.id = id;

}

public String getName() {

    return name;

}

public void setName(String name) {

    this.name = name;

}

public String getPwd() {

    return pwd;

}

public void setPwd(String pwd) {

    this.pwd = pwd;

}

public int getAge() {

    return age;

}

public void setAge(int age) {

    this.age = age;

}

 

}

2、编写获得数据库连接的工厂类:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

package cn.netjava.factory;

 

import java.sql.Connection;

import java.sql.DriverManager;

 

public class Connect2DBFactory {

    public static Connection getDBConnection() {

        Connection conn = null;

        try {

            Class.forName("com.mysql.jdbc.Driver");

            String url = "jdbc:mysql://localhost:3306/blogsystem";

            String user = "root";

            String password = "netjava";

            conn = DriverManager.getConnection(url, user, password);

        } catch (Exception e) {

            e.printStackTrace();

        }

 

        return conn;

    }

}

 

3、好戏开始啦,编写操作数据库的dao类

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

package cn.netjava.session;

 

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.ArrayList;

import java.util.List;

 

import cn.netjava.factory.Connect2DBFactory;

import cn.netjava.pojo.UserInfo;

 

public class NetJavaSession {

    /**

     * 解析出保存对象的sql语句

     *

     * @param object

     *            :需要保存的对象

     * @return:保存对象的sql语句

     */

    public static String getSaveObjectSql(Object object) {

        // 定义一个sql字符串

        String sql = "insert into ";

        // 得到对象的类

        Class c = object.getClass();

        // 得到对象中所有的方法

        Method[] methods = c.getMethods();

        // 得到对象中所有的属性

        Field[] fields = c.getFields();

        // 得到对象类的名字

        String cName = c.getName();

        // 从类的名字中解析出表名

        String tableName = cName.substring(cName.lastIndexOf(".") + 1,

                cName.length());

        sql += tableName + "(";

        List<String> mList = new ArrayList<String>();

        List vList = new ArrayList();

        for (Method method : methods) {

            String mName = method.getName();

            if (mName.startsWith("get") && !mName.startsWith("getClass")) {

                String fieldName = mName.substring(3, mName.length());

                mList.add(fieldName);

                System.out.println("字段名字----->" + fieldName);

                try {

                    Object value = method.invoke(object, null);

                    System.out.println("执行方法返回的值:" + value);

                    if (value instanceof String) {

                        vList.add("\"" + value + "\"");

                        System.out.println("字段值------>" + value);

                    } else {

                        vList.add(value);

                    }

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        }

        for (int i = 0; i < mList.size(); i++) {

            if (i < mList.size() - 1) {

                sql += mList.get(i) + ",";

            } else {

                sql += mList.get(i) + ") values(";

            }

        }

        for (int i = 0; i < vList.size(); i++) {

            if (i < vList.size() - 1) {

                sql += vList.get(i) + ",";

            } else {

                sql += vList.get(i) + ")";

            }

        }

 

        return sql;

    }

 

    public static List getDatasFromDB(String tableName, int Id) {

 

        return null;

 

    }

 

    /**

     * 将对象保存到数据库中

     *

     * @param object

     *            :需要保存的对象

     * @return:方法执行的结果;1:表示成功,0:表示失败

     */

    public int saveObject(Object object) {

        Connection con = Connect2DBFactory.getDBConnection();

        String sql = getSaveObjectSql(object);

        try {

            // Statement statement=(Statement) con.createStatement();

            PreparedStatement psmt = con.prepareStatement(sql);

            psmt.executeUpdate();

            return 1;

        } catch (SQLException e) {

            e.printStackTrace();

            return 0;

        }

    }

 

    /**

     * 从数据库中取得对象

     *

     * @param arg0

     *            :对象所属的类

     * @param id

     *            :对象的id

     * @return:需要查找的对象

     */

    public Object getObject(String className, int Id) {

        // 得到表名字

        String tableName = className.substring(className.lastIndexOf(".") + 1,

                className.length());

        // 根据类名来创建Class对象

        Class c = null;

        try {

            c = Class.forName(className);

 

        } catch (ClassNotFoundException e1) {

 

            e1.printStackTrace();

        }

        // 拼凑查询sql语句

        String sql = "select * from " + tableName + " where Id=" + Id;

        System.out.println("查找sql语句:" + sql);

        // 获得数据库链接

        Connection con = Connect2DBFactory.getDBConnection();

        // 创建类的实例

        Object obj = null;

        try {

 

            Statement stm = con.createStatement();

            // 得到执行查寻语句返回的结果集

            ResultSet set = stm.executeQuery(sql);

            // 得到对象的方法数组

            Method[] methods = c.getMethods();

            // 遍历结果集

            while (set.next()) {

                obj = c.newInstance();

                // 遍历对象的方法

                for (Method method : methods) {

                    String methodName = method.getName();

                    // 如果对象的方法以set开头

                    if (methodName.startsWith("set")) {

                        // 根据方法名字得到数据表格中字段的名字

                        String columnName = methodName.substring(3,

                                methodName.length());

                        // 得到方法的参数类型

                        Class[] parmts = method.getParameterTypes();

                        if (parmts[0] == String.class) {

                            // 如果参数为String类型,则从结果集中按照列名取得对应的值,并且执行改set方法

                            method.invoke(obj, set.getString(columnName));

                        }

                        if (parmts[0] == int.class) {

                            method.invoke(obj, set.getInt(columnName));

                        }

                    }

 

                }

            }

 

        } catch (Exception e) {

            e.printStackTrace();

        }

        return obj;

    }

}

 

4、开始测试效果怎么样:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package cn.netjava.tester;

 

import cn.netjava.pojo.UserInfo;

import cn.netjava.session.NetJavaSession;

 

public class Tester {

    public static void main(String args[]) {

        //获得NetJavaSession对象

        NetJavaSession session = new NetJavaSession();

        //创建一个UserInfo对象

        UserInfo user = new UserInfo();

        //设置对象的属性

        user.setId(6988);

        user.setAge(44);

        user.setPwd("pwd");

        user.setName("champion");

        //将对象保存到数据库中

        String sql = session.getSaveObjectSql(user);

        System.out.println("保存对象的sql语句:" + sql);

        //查找对象

        UserInfo userInfo = (UserInfo) session.getObject(

                "cn.netjava.pojo.UserInfo", 6988);

        System.out.println("获取到的信息:" + userInfo);

 

    }

}

 

5、打印出来的结果:

七、总节一下

      总的来说,java反射机制是一个很好用的东西,用它可以解决很多死的东西,因为反射机制的灵活行很大,有了他,我们就不要花太多的时间来写操做数据库的代码了,而是方法更多的时间在项目的逻辑功能上,这个可以很大的减少开发时间,而且代码的可读性好。先在的很多开源框架都是才用的反射机制,它只要配置文件,然后按规则来调用他的方法就可以了。


原创粉丝点击