概述
java范式机制是在运行状态中,对于任意一个类,都可能晓得这个类的所有属性和办法;对于任意一个对象,都可能调用它的任意一个办法和属性;这种动静获取的信息以及动静调用对象的办法的性能称为java语言的反射机制。
要想解剖一个类,必须要先获取到该类的字节码文件对象。而解剖应用的就是Class类中的办法。所以要先获取到每一个字节码文件对应的Class类型的对象
类的加载过程
Class类
获取Class类的三种形式
▪ 当用户想要获取任何一个Class类有三种形式:
– Object→getClass()
– 任何数据类型都有一个动态的class属性
– 通过Class.forName()
▪ 三种形式的比照:
– 第一种曾经创建对象,就意味着曾经产生了Class类
– 第二种须要导入对应的包,依赖太强
– 第三种罕用,只须要传入一个类的齐全限定名即可
反射的罕用api
▪ 获取类的构造方法
▪ 获取类的成员变量
▪ 获取类的成员办法
示例
罕用api
package com.msbline.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ClassAPI { public static void main(String[] args) throws Exception { Class<?> clazz = Class.forName("com.msbline.reflect.Student"); //获取成员变量,只能获取到public润饰的成员变量和办法 Field[] fields = clazz.getFields(); for(Field field:fields){ System.out.println(field); System.out.println(field.getName()); System.out.println(field.getType()); System.out.println(field.getModifiers()); System.out.println("-----------"); } System.out.println("=================="); //此办法返回的是以后类的所有属性,不仅仅局限于公共拜访修饰符, //所有的拜访修饰符都能够拿到,然而父类的拿不到 Field[] declaredFields = clazz.getDeclaredFields(); for(Field field:declaredFields){ System.out.println(field); System.out.println(field.getName()); System.out.println(field.getType()); System.out.println(field.getModifiers()); System.out.println("-----------"); } System.out.println("========================"); //反射在肯定水平上毁坏了封装性,须要正当应用 Field address = clazz.getDeclaredField("address");// 设置该属性是否能被拜访,true示意能够拜访 address.setAccessible(true); System.out.println(address.getName()); Object o = clazz.newInstance(); address.set(o,"北京市"); System.out.println(((Student)o).getAddress()); System.out.println("========================"); //获取该对象的一般办法,蕴含的办法范畴是以后对象及父类对象的所有public润饰的办法 Method[] methods = clazz.getMethods(); for(Method method:methods){// System.out.println(method); System.out.println(method.getName());// System.out.println(method.getModifiers()); System.out.println("---------------------"); } System.out.println("===================="); //获取以后类的所有办法,无论什么拜访修饰符,不包含父类 Method[] declaredMethods = clazz.getDeclaredMethods(); for(Method method:declaredMethods){ System.out.println(method.getName()); System.out.println("---------------------"); } System.out.println("=================="); Method add = clazz.getDeclaredMethod("add", int.class, int.class); add.setAccessible(true); Object o1 = clazz.newInstance(); add.invoke(o1,123,123); System.out.println("====================="); //获取对象的所有的构造方法,只能获取public润饰的公共的革新办法 Constructor<?>[] constructors = clazz.getConstructors(); for(Constructor constructor:constructors){ System.out.println(constructor.getName()); System.out.println(constructor.getModifiers()); } System.out.println("====================="); //获取所有的构造方法,无论是公有还是共有 Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); for(Constructor constructor:declaredConstructors){ System.out.println(constructor.getName()); System.out.println(constructor.getModifiers()); } //如何调用公有的构造方法呢? Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class, String.class); declaredConstructor.setAccessible(true); Object o2 = declaredConstructor.newInstance("msb", 44, "java"); System.out.println(((Student)o)); }}
利用
1、实体Emp
package com.msbline.entity;public class Emp { private Integer empno; private String ename; private String job; private Integer mgr; private String hiredate; private Double sal; private Double comm; private Integer deptno; public Emp() { } public Emp(Integer empno, String ename, String job, Integer mgr, String hiredate, Double sal, Double comm, Integer deptno) { this.empno = empno; this.ename = ename; this.job = job; this.mgr = mgr; this.hiredate = hiredate; this.sal = sal; this.comm = comm; this.deptno = deptno; } public Integer getEmpno() { return empno; } public void setEmpno(Integer empno) { this.empno = empno; } public String getEname() { return ename; } public void setEname(String ename) { this.ename = ename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public Integer getMgr() { return mgr; } public void setMgr(Integer mgr) { this.mgr = mgr; } public String getHiredate() { return hiredate; } public void setHiredate(String hiredate) { this.hiredate = hiredate; } public Double getSal() { return sal; } public void setSal(Double sal) { this.sal = sal; } public Double getComm() { return comm; } public void setComm(Double comm) { this.comm = comm; } public Integer getDeptno() { return deptno; } public void setDeptno(Integer deptno) { this.deptno = deptno; } @Override public String toString() { return "Emp{" + "empno=" + empno + ", ename='" + ename + ''' + ", job='" + job + ''' + ", mgr=" + mgr + ", hiredate=" + hiredate + ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + '}'; }}
2、实体Dept
package com.msbline.entity;public class Dept { private int deptno; private String dname; private String loc; public Dept() { } public Dept(int deptno, String dname, String loc) { this.deptno = deptno; this.dname = dname; this.loc = loc; } public int getDeptno() { return deptno; } public void setDeptno(int deptno) { this.deptno = deptno; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } @Override public String toString() { return "Dept{" + "deptno=" + deptno + ", dname='" + dname + ''' + ", loc='" + loc + ''' + '}'; }}
3、BaseDaoImpl
package com.msbline.reflect;import com.msbline.entity.Dept;import com.msbline.jdbc.DBUtil;import com.msbline.entity.Emp;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.ResultSetMetaData;import java.util.ArrayList;import java.util.Iterator;import java.util.List;/** * 要查问N张表的数据,然而不想写N多办法, * 是否写一个办法实现所有表的查问工作 * */public class BaseDaoImpl { /** * 对立查问表的办法 * @param sql sql语句 * @param params sql参数 * @param clazz sql语句查问返回的对象 * @return */ public List getRows(String sql,Object[] params,Class clazz){ List list = new ArrayList(); Connection connection = null; PreparedStatement pstmt = null; ResultSet resultSet = null; try{ connection = DBUtil.getConnection(); pstmt = connection.prepareStatement(sql); //给sql语句填充参数 if(params != null){ for(int i = 0; i<params.length; i++){ pstmt.setObject(i+1,params[i]); } } //开始执行查问 resultSet = pstmt.executeQuery(); //将返回的后果搁置到不同的对象中 //获取后果汇合的元数据对象 ResultSetMetaData metaData = resultSet.getMetaData(); //判断查问到的每一行记录中蕴含多少个列 int columnCount = metaData.getColumnCount(); while (resultSet.next()){ //创立搁置具体后果属性的对象 Object obj = clazz.newInstance(); for(int i = 0; i<columnCount; i++){ //从后果汇合中获取繁多列的值 Object objValue = resultSet.getObject(i + 1); //获取列的名称 String columnName = metaData.getColumnName(i+1).toLowerCase(); //获取类中属性的名称 Field field = clazz.getDeclaredField(columnName); //获取类中属性对应的set办法 Method method = clazz.getMethod(getSetName(columnName), field.getType()); if(objValue instanceof Number){ Number number = (Number)objValue; String fname = field.getType().getName(); if("int".equals(fname) || "java.lang.Integer".equals(fname)){ method.invoke(obj,number.intValue()); } else if("byte".equals(fname) || "java.lang.Byte".equals(fname)){ method.invoke(obj,number.byteValue()); }else if("short".equals(fname) || "java.lang.Short".equals(fname)){ method.invoke(obj,number.shortValue()); }else if("long".equals(fname) || "java.lang.Long".equals(fname)){ method.invoke(obj,number.longValue()); }else if("float".equals(fname) || "java.lang.Float".equals(fname)){ method.invoke(obj,number.floatValue()); }else if("double".equals(fname) || "java.lang.Double".equals(fname)){ method.invoke(obj,number.doubleValue()); } } else { method.invoke(obj,objValue); } } list.add(obj); } }catch (Exception e){ e.printStackTrace(); }finally { DBUtil.close(connection,pstmt,resultSet); } return list; } public String getSetName(String name){ return "set"+name.substring(0,1).toUpperCase()+name.substring(1); } public static void main(String[] args) { BaseDaoImpl baseDao = new BaseDaoImpl();// List rows = baseDao.getRows("select empno,ename,sal,deptno from emp where deptno=?",// new Object[]{10}, Emp.class); List rows = baseDao.getRows("select deptno,dname,loc from dept", new Object[]{}, Dept.class); System.out.println(rows.size()); for(Iterator iterator = rows.iterator();iterator.hasNext();){ Dept dept = (Dept) iterator.next(); System.out.println(dept); } }}