zoukankan      html  css  js  c++  java
  • 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

     打包成功会有这个信息

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

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

  • 相关阅读:
    Nginx + uWSGI 配置django
    django视图缓存的实现
    scrapy 资料
    scrapy 安装
    程序题做题一般步骤
    检查代码的一般步骤
    Mathematical-Analysis-I-4
    Mathematical-Analysis-I-3
    Mathematical-Analysis-I-1
    Mathematical-Analysis-I-2
  • 原文地址:https://www.cnblogs.com/mvpmvp/p/13418484.html
Copyright © 2011-2022 走看看