less than 1 minute read

反射介绍

Java反射机制是在运行状态中,对于任意一个类,可以知道类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

获取Class对象的四种方式

  1. 知道具体类的情况下

     Class<A2> a2Class = A2.class;
    

    不会初始化

  2. Class.forName()传入类的路径

     Class a2Class = Class.forName("javaTest.A2");
    

    会初始化

  3. 对象实例获取

     A2 a2 = new A2();
     Class<? extends A2> a2Class = a2.getClass();
    

    会初始化

  4. 类加载器传入类路径获取

     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修改参数

反射优缺点

优点

运行期类型的判断,动态加载类,提高代码灵活度

缺点

  1. 性能瓶颈:反射相当于一系列解释操作,通知JVM要做的事情,性能比直接的Java代码要慢很多。
  2. 安全问题,让我们可以动态操作改变类的属性同时也增加了类的安全隐患。

应用场景

平时开发基本用不到,但是框架里面大量使用。反射是框架设计的灵魂

转载自JavaGuide

Tags:

Categories:

Updated: