一、什么是反射,反射的概念
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
打包成功会有这个信息
这个时候就可以去文件里找了
然后我们就可以导入依赖了 ,直接拿过来就能用