概述

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);        }    }}