Java Reflection

Reflection in Java

反射是一种API,用于在运行时检查修改方法,类,接口的行为。

  • 反射所需的类在java.lang.reflect包下提供。
  • 反射为我们提供了有关对象所属类的信息,以及可以使用该对象执行的该类的方法。
  • 通过反射,我们可以在运行时调用方法,而与它们所使用的访问说明符无关。
    在这里插入图片描述

反射可用于获取有关–的信息

  • 用于获取对象所属的类的名称
  • 构造函数 getConstructors()方法用于获取对象所属类的公共构造函数
  • 方法 getMethods()方法用于获取对象所属类的公共方法
public class ReflectionTest {

    private String s;
    public ReflectionTest(){
        this.s="init ReflectionTest class field";
    }

    public void method1(){
        System.out.println("The String for ReflectionTest s value:" + s);
    }

    public void method2(int num){
        System.out.println("The method2 param incoming is "+ num);
    }

    private void method() {
        System.out.println("private method invoked");
    }
}


public class DemoTestMain {
    public static void main(String[] args) throws Exception {
        //to create a tested class object
        ReflectionTest refObj = new ReflectionTest();
        //1. 通过getClass获取类对象
        Class<?> cls = refObj.getClass();
		
		//2.通过字节码获取对象
		//Class<?> cls2 = ReflectionTest.lcass;
		//3.通过Class.forName获取对象
		//Class<?> cls3 = Class.forName("com.demo.ReflectionTest");
		
        System.out.println("The name for the obj is " + cls.getName());
        System.out.println("The method for this obj ");

        //get constructor for the class
        Constructor constructor = cls.getConstructor();
        System.out.println("The name for class constructor is "+constructor.getName());

        //get all the method for this Class obj
        Method[] methods = cls.getMethods();

        //for Each all the method
        for (int i = 0; i < methods.length; i++) {
            System.out.println("for the class object method " + methods[i]);
        }

        //get specified method
        Method speMethod = cls.getMethod("method2", int.class);
        System.out.println("specified method name is " + speMethod.getName());
        // invoke specified method
        speMethod.invoke(refObj, 10);

        //get desired field for the class 
        Field sFiled = cls.getDeclaredField("s");
        //allow the object to access the filed,because the field was private
        sFiled.setAccessible(true);
        sFiled.set(refObj,"Java Reflection Demo");

        //get desired method for the class
        Method method2 = cls.getDeclaredMethod("method2", int.class);
        method2.invoke(refObj,99);

    }

}

输出:

The name for the obj is com.seny.test.ReflectionTest
The method for this obj 

The name for class constructor is com.seny.test.ReflectionTest

for the class object method public void com.seny.test.ReflectionTest.method2(int)
for the class object method public void com.seny.test.ReflectionTest.method1()
for the class object method public final void java.lang.Object.wait() throws java.lang.InterruptedException
for the class object method public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
for the class object method public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
for the class object method public boolean java.lang.Object.equals(java.lang.Object)
for the class object method public java.lang.String java.lang.Object.toString()
for the class object method public native int java.lang.Object.hashCode()
for the class object method public final native java.lang.Class java.lang.Object.getClass()
for the class object method public final native void java.lang.Object.notify()
for the class object method public final native void java.lang.Object.notifyAll()

specified method name is method2
The method2 param incoming is 10
The method2 param incoming is 99

重要观察:

如果知道方法的名称和参数类型,则可以通过反射调用该方法。为此,我们使用以下两种方法
getDeclaredMethod():创建要调用的方法的对象。该方法的语法是

Class.getDeclaredMethod(name,parameterType)
name-要创建其对象的方法的名称
parameterType-参数是Class对象的数组

invoke():要在运行时调用类的方法,我们使用以下方法–

Method.invoke(Object,parameter)
如果该类的方法不接受任何方法参数,则将null用作参数。

通过反射,我们可以在类的类对象的帮助下访问类的私有变量和方法,并使用对象来调用方法,如上所述。为此,我们使用以下两种方法。
Class.getDeclaredField(FieldName):用于获取私有字段。返回指定类型字段名称的对象。
Field.setAccessible(true):允许访问该字段,而与该字段使用的访问修饰符无关。

使用反射的优势:

  • 可扩展性功能:应用程序可以通过使用其完全限定的名称创建可扩展性对象的实例来使用外部的用户定义类。
  • 调试和测试工具:调试器使用反射的特性去检测类的私有成员。

缺点:

  • 性能开销:反射性操作的性能比非反射性操作慢,因此应避免在对性能敏感的应用程序中对于经常调用的代码段要尽量避免使用反射操作。
  • 内部暴露:反射代码破坏了抽象,因此可能会随着平台升级而改变行为。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值