java反射机制

定义

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。

为什么要有反射呢?

  • 反射让开发人员可以通过外部类的全路径名创建对象,并使用这些类,实现一些扩展的功能
  • 反射让开发人员可以枚举出类的全部成员,包括构造函数、属性、方法。以帮助开发者写出正确的代码。
  • 测试时可以利用反射 API 访问类的私有成员,以保证测试代码覆盖率。
    举例子
    1.当我们的程序在运行时,需要动态的加载一些类这些类开始不用加载到jvm,而是在运行时根据需要才加载,举个例子我们的项目底层有时是用mysql,有时用oracle,需要动态地根据实际情况加载驱动类,这个时候反射就有用了,假设 com.java.driver.myqlConnection,com.java.driver.oracleConnection这两个类我们要用,这时候我们的程序就写得比较动态化,通过Class tc = Class.forName(“com.java.dbtest.TestConnection”);通过类的全类名让jvm在服务器中找到并加载这个类,
    2.spring,会发现当你配置各种各样的bean时,是以配置文件的形式配置的,配置需要的bean,spring容器就会根据需求去动态加载.
    3.在JBDC里也有反射获取加载类,账号,密码

使用

  • 反射获取 Class 类 (Class)
  • 反射获取类中的所有字段 (Field)
  • 反射获取类中的所有构造方法(Constructor)
  • 反射获取类中的方法 (Method)

Field 类:提供有关类的属性信息,以及对它的动态访问权限。它是一个封装反射类的属性的类。
Constructor 类:提供有关类的构造方法的信息,以及对它的动态访问权限。它是一个封装反射类的构造方法的类。
Method 类:提供关于类的方法的信息,包括抽象方法。它是用来封装反射类方法的一个类。
Class 类:正在运行的 Java 应用程序中的类的实例。

实践

首先写一个类

package reflection;
/**
* 测试类
*/
public class TestR {

   //私有属性name
   private String name;

   //公共属性password
   public String password;

   //构造方法
   public TestR() {
   }

   //有参构造方法
   public TestR(String name, String password) {
       this.name = name;
       this.password = password;
   }

   public void setName(String name) {
       this.name = name;
   }

   public String test(String val){
       System.out.println(val +"   name:"+name+"  password:"+password);
       return "test";
   }
}

反射应用

  //通过包路径获取 TestClass
       Class testClass = Class.forName("com.test.reflection.TestR");
       Class testClass1 = TestR.class;

       //获取字段属性
        // 1.获取所有声明的字段属性
        Field[] declaredFieldList = testClass.getDeclaredFields();
        for (Field declaredField : declaredFieldList) {
            System.out.println("declared Field: " + declaredField);
        }

        // 2.获取所有公有的字段属性
        Field[] fieldList = testClass.getFields();
        for (Field field : fieldList) {
            System.out.println(" public field: " + field);
        }

        //构造方法
        // 3.获取所有声明的构造方法
        Constructor[] declaredConstructorList = testClass.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructorList) {
            System.out.println("testClass declared Constructor: " + declaredConstructor);
        }

        // 4.获取所有公有的构造方法
        Constructor[] constructorList = testClass.getConstructors();
        for (Constructor constructor : constructorList) {
            System.out.println("testClass constructor: " + constructor);
        }

        //方法
        // 1.获取所有声明的函数
        Method[] declaredMethodList = testClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethodList) {
            System.out.println("declared Method: " + declaredMethod);
        }
        // 2.获取所有公有的函数
        Method[] methodList = testClass.getMethods();
        for (Method method : methodList) {
            System.out.println("method: " + method);
        }

      
        Constructor testConstructor = testClass.getDeclaredConstructor(String.class);
        // 如果私有的函数,需要设置accessible true
        testConstructor.setAccessible(true);

        // 使用构造方法的newInstance方法创建对象,传入构造方法所需参数,如果有多个参数,用','连接即可
        Object test = testConstructor.newInstance("pengzc","123");

        Field testPasswordField = testClass.getDeclaredField("password");
        // 使用字段的set方法设置字段值,传入此对象以及参数值
        testPasswordField.set(test,"456");

        // 4.获取声明的函数,传入所需参数的类名,如果有多个参数,用','连接即可
        Method studentShowMethod = testClass.getDeclaredMethod("show",String.class);
        // 如果私有的函数,需要设置accessible true
        studentShowMethod.setAccessible(true);
        // 使用函数的invoke方法调用此函数,传入此对象以及函数所需参数,如果有多个参数,用','连接即可。函数会返回一个Object对象,使用强制类型转换转成实际类型即可
        Object result = studentShowMethod.invoke(test,"test哈哈哈哈");
        System.out.println("result: " + result);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值