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