java中的反射详解

一、什么是反射,反射的概念

     JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

 二、反射是怎么实现的

  程序运行的时候首先会通过javac把.java文件编译成.class文件,然后保存在硬盘中,当使用new的构造方法来创建一个对象的时候,类加载器就会把数据从硬盘中读入内存,内存的方法区中就会存在这个方法,堆区中会创建一个对象来指向这个方法,这就是反射的实现过程。

程序会在对类第一次使用的时候进行类加载,分为以下五种情况:

1、new一个对象的构造方法

2、new一个类的子类的构造方法

3、调用一个累的static成员变量或方法

4、运行含有main的方法类

5、调用Class.forName("类额完全限定名")

拿到class对象的三种方式

1、Class.forName("类额完全限定名")

2、类名.class

3、对象名.getclass()

 

User user=new User();
        Class clz=Class.forName("类的完全限定名");
        System.out.println(clz);
        System.out.println(user.getClass());
        System.out.println(User.class);
//输出的结果是完全相等的

 

举例说明(Jdbc的封装)

普通的jdbc都会很麻烦,每一个表的增删查改都要去挨个写方法,这里我们对数据库的dao层尽心了封装,把逻辑封装成一个jdbcutil实现方法如下:

通过查询所有信息来举例,其他的都类似

public static <T> List<T> executeQuery(String sql,Class<T> clz,Object... params) {//这里参数我们采用数据库语句和泛型类还有需要用到的参数,这里就是采用的反射机制,根据类名.calss来获取对象
        List<T> list = new ArrayList<T>();//由于不知道具体对象,这里也采用泛型
        Connection con = getConnection();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            pstmt = con.prepareStatement(sql);
            if(params != null) {
                for(int i = 0; i < params.length; i++) {
                    pstmt.setObject(i + 1, params[i]);
                }
            }
            rs = pstmt.executeQuery();
            while (rs.next()) {
                // 先创建一个对象
                T t = clz.newInstance();//调用无参构造方法
                // 读数据库的值 为 t对象的属性赋值
                Field[] fields = clz.getDeclaredFields();//获取类的所有属性
                for(Field field : fields) {
                   String fieldname = field.getName();
                   // 把属性名 当做字段名 从 rs中 获取数据
                    try{
                        Object value = rs.getObject(fieldname);//获取这个属性和值
                        field.setAccessible(true);//由于实体类的属性可能是private所以要获取权限
                        field.set(t,value);//把属性和值放到泛型类中
                    }catch (Exception ex) {
                        System.out.println(fieldname + "在数据表中没有这个字段");
                    }
                }
                list.add(t);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }finally {
            close(rs,pstmt,con);
        }
        return list;
    }

为了方便实用这个封装,下面演示一下其他项目如何导入这个jar包,要注意以下几个地方,然后点install

 

 

 打包成功会有这个信息

 

 

 这个时候就可以去文件里找了

 

 

然后我们就可以导入依赖了 ,直接拿过来就能用

 

posted @ 2020-08-02 12:51  西凉锦马超  阅读(251)  评论(0编辑  收藏  举报