介绍
指在运行状态中:
任意一个类,都能够知道这个类所有属性和方法;
任意一个对象,都能调用它的任意一个属性和方法;
获取Class对象的两种方式
动态获取信息,需依靠Class对象
Java获取Class对象方法:
- 知道具体类
Class alunbarClass = TargetObject.class;
- 不知道具体类
//遍历包下面的类来获取Class对象
Class alunbarClass1 = Class.forName("cn.yufchen.TargetObject");
静态编译和动态编译
- 静态编译:在编译时确定类型,绑定对象
- 动态编译:运行时确定类型,绑定对象
优缺点
- 优点:运行期类型的判断,动态加载类,提高代码灵活度。
- 缺点:性能瓶颈:反射相当于一系列解释操作,通知JVM要做的事情,性能比直接的java代码要慢很多。
安全问题:动态操作改变类的属性同时也增加了类的安全隐患。
练习
package com.yufchen.tool;
//供com.yufchen.tool.useReflect测试反射机制用
public class TargetObject {
private String value;
public TargetObject() {
value = "yufchen";
}
public void publicMethod(String s) {
System.out.println("I am " + s);
}
private void privateMethod() {
System.out.println("value is " + value);
}
}
package com.yufchen.tool;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class useReflect {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获取TargetObject类的Class对象并且创建TargetObject类实例
Class<?> targetClass = Class.forName("com.yufchen.tool.TargetObject");
TargetObject targetObject = (TargetObject) targetClass.newInstance();
//获取所有类中所有定义的方法
Method[] methods = targetClass.getDeclaredMethods();
for (Method method : methods) {
System.out.print(method.getName() + ' ');
}
System.out.println();
//获取指定方法并调用
Method publicMethod = targetClass.getDeclaredMethod("publicMethod", String.class);
System.out.print("获取指定方法(publicMethod)并调用: ");
publicMethod.invoke(targetObject, "yufchen");
//获取指定参数并对参数进行修改
Field field = targetClass.getDeclaredField("value");
//为了对类中的参数进行修改 取消安全检查
field.setAccessible(true);
field.set(targetObject, "Notyufchen");
Method privateMethod = targetClass.getDeclaredMethod("privateMethod");
//为了调用private方法 取消安全检查
privateMethod.setAccessible(true);
privateMethod.invoke(targetObject);
}
}
//输出
publicMethod privateMethod
获取指定方法(publicMethod)并调用: I am yufchen
value is Notyufchen
扩展
- why used Class<?> ?
? 是通配符,对比Class<T>在于,?不限制参数必须要有具体的类型。