Java反射
反射介绍
Java反射机制是在运行状态中,对于任意一个类,可以知道类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
获取Class对象的四种方式
-
知道具体类的情况下
Class<A2> a2Class = A2.class;
不会初始化
-
Class.forName()传入类的路径
Class a2Class = Class.forName("javaTest.A2");
会初始化
-
对象实例获取
A2 a2 = new A2(); Class<? extends A2> a2Class = a2.getClass();
会初始化
-
类加载器传入类路径获取
Class<?> a2Class = ClassLoader.getSystemClassLoader().loadClass("javaTest.A2");
不会初始化
使用反射调用类的私有方法和设置私有属性
//A2有一个私有属性value和两个私有方法。无法通过创建A2对象来访问这些私有方法和属性,但是反射可以
public class A2 {
private String value;
private void setValue(String value) {
this.value = value;
}
static {
System.out.println("静态代码块");
}
private void sayHello() {
System.out.println("hello" + value);
}
}
public class Demo {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获取A2类,有四种方法,详见上文。
Class<A2> a2Class = A2.class;
//创建对象。也可以用A2 a2=new A2();
A2 a2 = a2Class.newInstance();
//获取类有哪些方法
Method[] declaredMethods = a2Class.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
//调用setValue私有方法
Method setValue = a2Class.getDeclaredMethod("setValue", String.class);
//取消安全检查,不然无法修改
setValue.setAccessible(true);
setValue.invoke(a2, "反射");
//调用sayHello
Method sayHello = a2Class.getDeclaredMethod("sayHello");
sayHello.setAccessible(true);
sayHello.invoke(a2);
//修改value私有属性
Field value = a2Class.getDeclaredField("value");
value.setAccessible(true);
value.set(a2, "修改参数");
sayHello.invoke(a2);
}
}
结果如下
静态代码块
private void javaTest.A2.setValue(java.lang.String)
private void javaTest.A2.sayHello()
hello反射
hello修改参数
反射优缺点
优点
运行期类型的判断,动态加载类,提高代码灵活度
缺点
- 性能瓶颈:反射相当于一系列解释操作,通知JVM要做的事情,性能比直接的Java代码要慢很多。
- 安全问题,让我们可以动态操作改变类的属性同时也增加了类的安全隐患。
应用场景
平时开发基本用不到,但是框架里面大量使用。反射是框架设计的灵魂
转载自JavaGuide