java反射使用

反射的概念:

在程序运行期间,动态获取和调用类的成员或者成员方法的机制,反射可以无视修饰符访问权限检查(调用的时候使用setAccessible(true)取消访问检查)。

反射核心类:

  1. java.lang.class类:这个类是java的类的字节码文件对象类,每一个类都会有一个对应的class对象。有三种方式可以获取到一个类的Class对象
    1. 类.class,比如:Student.class
    2. 使用类的实例对象调用getClass方法。getClass方法是定义在Object中的
    3. Class.forName("类的全路径:报名+类名")
  2. Constructor构造函数对象类,使用该类的实例调用newInstance()方法,即可通过该构造函数对象创建一个对应的类的实例对象,可以通过类的Class对象来获取类的构造函数,主要的获取函数有几个:
    Class<Student> clazz = Student.class;
    Constructor<Student> constructor = clazz.getDeclaredConstructor();
    constructor.setAccessible(true);    //私有构造方法需要取消访问检查
    Student student1 = constructor.newInstance();
    1. getConstructors():返回所有的公共构造函数对象数组,不需要参数
    2. getDeclaredConstructors():返回所有的(包括不是public修饰的)构造函数对象数组,不需要参数
    3. getDeclaredConstructor(),返回一个构造函数对象(可以是非public的),参数需要跟实际的构造函数的参数类型对应(使用构造函数参数的class对象),如果没有就不需要
    4. getConstructor():与3的区别是只能获取公共的构造函数
  3. Field,类的成员变量对象,使用该对象的get或set方法可以动态访问类的成员变量(私有的需要取消访问检查,需要传入对应的类的实例对象),使用class对象获取该对象的方法:
    Constructor<Student> constructor = clazz.getConstructor();
    Student student2 = constructor.newInstance();
    //        clazz.getField("age");
    //        Field[] declaredFields = clazz.getDeclaredFields();
    //        Field[] fields = clazz.getFields();
    Field age = clazz.getDeclaredField("age");
    age.setAccessible(true);
    age.setInt(student2,58);
    age.get(student2);
    1. getFields():返回全部公共成员变量对象数组,不需参数
    2. getDeclaredFields():返回全部(包括非公共)的成员变量对象数组,不需要参数
    3. getField("age"),返回指定的公共的成员变量对象,参数是需要获取的字段名
    4. getDeclaredField("age"):返回指定的成员变量对象,可以是私有的
  4. methods成员方法对象,使用该对象的invoke方法可以动态调用方法对象所代码的方法(需要传入类的实例),使用class对象获取methods的四种方法:
    1. getMethods(),获取所有的公共成员方法对象数组
    2. getDeclaredMethods():获取所有的包括非公共的成员方法的方法对象数组
    3. getMethod:获取指定的公共方法对象,参数是方法名
    4. getDeclaredMethod():可以获取私有的方法的方法对象,参数是方法名
 Class<Student> clazz = Student.class;
 Constructor<Student> constructor = clazz.getConstructor();
 Student student2 = constructor.newInstance();

//        Method[] methods = clazz.getMethods();
//        clazz.getDeclaredMethods();
Method method = clazz.getMethod("study");
//method.setAccessible(true);    私有方法需要
method.invoke(student2);
//        clazz.getDeclaredMethod();

反射的优缺点:

        有点:反射提高了程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;

        缺点:1、性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。      
       2、使用反射会模糊程序内内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。   至于执行效率的话,还可以,因为它是一种强类型语言,执行效率不错。不过,建议将反射过后,保存进 cache中。

        3、破坏程序的封装性,会带来安全问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java反射可以让我们在运行时获取和操作类的信息,包括类的属性、方法、构造函数等。下面是一个使用Java反射的简单案例: 假设我们有一个类Person: ```java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public void sayHello() { System.out.println("Hello, my name is " + name + ", I am " + age + " years old."); } } ``` 现在,我们可以使用反射来获取和调用Person类的构造函数和方法: ```java import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class ReflectionExample { public static void main(String[] args) throws Exception { // 获取Person类的Class对象 Class<Person> personClass = Person.class; // 获取Person类的构造函数 Constructor<Person> constructor = personClass.getConstructor(String.class, int.class); // 使用构造函数创建Person对象 Person person = constructor.newInstance("Tom", 20); // 获取Person类的sayHello方法 Method sayHelloMethod = personClass.getMethod("sayHello"); // 调用sayHello方法 sayHelloMethod.invoke(person); } } ``` 以上代码,我们首先通过`Person.class`获取了Person类的Class对象,然后使用`getConstructor`方法获取了Person类的构造函数,并使用构造函数创建了一个Person对象。接着,我们使用`getMethod`方法获取了Person类的`sayHello`方法,并使用`invoke`方法调用了该方法。最终,我们输出了`Hello, my name is Tom, I am 20 years old.`。 这只是一个简单的反射案例,实际上Java反射还可以做很多其他的事情,比如动态代理、注解处理等等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值