Java反射机制是指在运行时,动态获取类或者对象的信息,及动态调用对象方法的功能 ;
Java反射机制具有3个动态性质:
- 运行时生成对象实例
- 运行期间调用方法
- 运行时更改属性
在Java中,通过反射API,程序可以 ”看到“ 对象的很多信息,例如: 哪个类的实例,这个类有哪些属性和方法,每个属性内部状态是什么,等等;
当然不仅仅是“看到” 这些信息,还可以在运行时做很多事情,例如:在运行时加载编译期间并不知道名字的类,探知类和对象的结构信息,创建类的实例,调用创建实例的属性和方法,等等;
专业说法就是:
反射是指应用能够自描述和自控制的机制和能力。
通过反射,可以实现以下功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的方法和属性
- 在运行时调用任意一个对象的方法
Java反射常用API:
- Class类:反射的核心类,反射所有操作都是围绕该类来生成的,通过Class类,可以获取类的属性,方法等内容信息
- Field类:类的属性,可以获取和设置类中的属性的值
- Method类:类的方法,他可以用来获取类中方法的信息,或者执行方法。
- Constructor类:类的构造方法
在Java程序中使用反射的基本步骤如下:
- 导入java.lang.reflect.*;
- 获得需要操作的类的Java.lang.Class对象
- 调用Class的方法获取Field、Method等对象
- 使用反射API进行操作
获取Class对象:
获取类对象 有三种方法:
调用某个对象的getClass()方法
调用某个类的class属性来获取该类对应的Class对象(性能更高,代码更安全)
使用类的forName()静态方法(性能较低,只需知道类的完全限定名)
//1.加载这个类 创建类实例
Class clss = Class.forName("com.accp.entity.Dept");
//2.通过这个类对象创建类实例
Class cls= Dept.class;
//3.根据类的对象 创建类实例
Dept dept = new Dept();
Class clz = dept.getClass();
通过class对象 获取属性信息
Class cls = Class.forName("com.accp.entity.Dept");
//获取部门类定义的字段 getFields 公有的字段 ,.getDeclaredFields全部字段
Field[] fields = cls.getDeclaredFields();
//遍历显示属性信息
System.out.println("field ..:");
for (Field field : fields) {
//System.out.println("\t\tModifier:"+Modifier.toString(field.getModifiers())+",\tType :"+field.getType().getName()+",\tName :"+field.getName()+"\n");
System.out.println(" Modifier: "+Modifier.toString(field.getModifiers()));
System.out.println(" Type: " +field.getType().getName());
System.out.println(" Name: "+field.getName());
System.out.println();
}
通过class对象 获取方法信息
Class clz = Class.forName("com.accp.entity.Dept");
Method[] methods = clz.getMethods();
for (Method method : methods) {
System.out.println("........................."+method+"....Modifier: "+method.getModifiers()+" ..."+Modifier.toString(method.getModifiers()));
//Modifier:
System.out.print(Modifier.toString(method.getModifiers())+" ");
//ReturnType
System.out.print(method.getReturnType().getName()+" ");
//MethodName
System.out.print(method.getName()+"( ");
//ParameterType
if(method.getParameterTypes().length>0){
//遍历 参数数组
for (Class param : method.getParameterTypes()) {
System.out.print(param.getName()+" ");
}
}
System.out.print(")");
//ExceptionType
if (method.getExceptionTypes().length>0) {
System.out.print(" throws ");
//遍历抛出的异常数组
for (Class exception : method.getExceptionTypes()) {
System.out.println(exception.getName());
}
}
System.out.println();
}
Class clz = Class.forName("com.accp.entity.Dept");
Constructor[] constructors = clz.getConstructors();
System.out.println("Constructor...:");
for (Constructor constructor : constructors) {
//Modifier
System.out.print(" : "+Modifier.toString(constructor.getModifiers()));
//返回了类的完全限定名,是不是意味着Constructor中的name实际也是返回值
//ConstructorName
System.out.print(""+constructor.getName());
System.out.print("(");
//遍历 构造函数的参数
if (constructor.getParameterTypes().length>0) {
for (Class param : constructor.getParameterTypes()) {
System.out.print(param.getName()+" ");
}
}
System.out.println(")");
System.out.println();
}
//通过构造函数直接实例化出对象 无法通过私有构造函数 创建对象
Dept dept = (Dept) constructors[0].newInstance();
dept.setDeptno(900);
System.out.println("0 "+dept);
Dept dept1 = (Dept) constructors[1].newInstance(901,"就业部","一楼");
System.out.println("1 "+dept1);
Dept dept2 = (Dept) constructors[2].newInstance("事业部","二楼");
System.out.println("2 "+dept2);
动态构建对象,但是必须有相对应的构造函数
//1.加载这个类 创建类实例
Class cls = Class.forName("com.accp.entity.Dept");
Object object= cls.newInstance();//调用这个类的无餐构造函数
System.out.println(object);
//调用有参构造函数 构建实例
Constructor constructor = cls.getConstructor(Integer.class,String.class,String.class);
Object obj1 = constructor.newInstance(12,"就业部","三楼");
System.out.println(obj1);