java的反射机制

1.什么是JAVA的反射机制

Java的反射机制是指在运行时,可以获取、检查和操作类、对象、方法、字段等程序的内部信息的能力。反射机制使得程序可以动态地获取类的信息、实例化对象、调用方法、访问和修改字段等,而无需在编译时明确知道这些信息。反射机制为Java提供了灵活性和可扩展性,但也需要谨慎使用,因为它会牺牲一些性能和类型安全

2.提供了什么功能

反射机制的核心类是`java.lang.Class`,它代表一个Java类的元数据。通过`Class`类,可以执行以下操作:

1. **获取类的信息:** 可以获取类的名称、包信息、父类、接口、方法、字段等信息。

2. **实例化对象:** 可以通过类的构造器来实例化对象,即使在编译时无法确定具体的类。

3. **调用方法:** 可以调用类中的方法,包括私有方法,也可以传递参数执行方法。

4. **访问和修改字段:** 可以访问和修改对象的字段,包括私有字段。

5. **处理数组:** 可以创建、访问和修改数组对象。

反射机制通常用于以下情况:

- 开发通用性高的框架和工具,例如ORM(对象关系映射)库、依赖注入容器等。

- 编写调试工具和性能分析工具。

- 处理配置文件,动态加载类和资源。

- 在特殊情况下,需要与不可知类型的对象交互。

虽然反射提供了强大的能力,但也需要注意一些潜在问题,如性能开销、类型安全性、编译时检查的缺失等。因此,在使用反射时需要小心谨慎,确保合理使用,并且尽量避免破坏封装性和类型安全性。

3.JDK中提供的Reflection API

JDK中提供了一组用于反射的API,这些API允许你在运行时获取和操作类、方法、字段、构造器等元数据信息。以下是主要的Reflection API类和接口:

1. `java.lang.Class`:代表一个Java类或接口的元数据信息。它是反射的入口点之一,用于获取类的各种信息。

   - `getName()`:获取类的全限定名。
   - `getSuperclass()`:获取父类的Class对象。
   - `getInterfaces()`:获取实现的接口数组。
   - `getDeclaredMethods()`:获取声明的方法数组。
   - `getDeclaredFields()`:获取声明的字段数组。
   - 等等。

2. `java.lang.reflect.Method`:代表类的方法,可以用于获取和调用类的方法。

   - `getName()`:获取方法名。
   - `getParameterTypes()`:获取方法的参数类型数组。
   - `invoke(Object obj, Object... args)`:调用方法。
   - 等等。

3. `java.lang.reflect.Field`:代表类的字段,可以用于获取和设置类的字段值。

   - `getName()`:获取字段名。
   - `getType()`:获取字段的类型。
   - `get(Object obj)`:获取字段的值。
   - `set(Object obj, Object value)`:设置字段的值。
   - 等等。

4. `java.lang.reflect.Constructor`:代表类的构造器,可以用于实例化对象。

   - `getParameterTypes()`:获取构造器的参数类型数组。
   - `newInstance(Object... initargs)`:创建类的实例。
   - 等等。

这些API允许你在运行时执行各种操作,如创建对象、调用方法、访问字段等,而不需要在编译时了解类的具体信息。反射是一种非常强大但也复杂的特性,需要小心使用,以确保类型安全和性能。

4.在动态代理中使用反射

1、定义抽象角色

public interface Subject {

public void Request();

}

2、定义真实角色

public class RealSubject implements Subject {

@Override

public void Request() {

// TODO Auto-generated method stub

System.out.println("RealSubject");

}

}

3、定义代理角色

public class DynamicSubject implements InvocationHandler {

private Object sub;

public DynamicSubject(Object obj){

this.sub = obj;

}

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

// TODO Auto-generated method stub

System.out.println("Method:"+ method + ",Args:" + args);

method.invoke(sub, args);

return null;

}

}

4、通过Proxy.newProxyInstance构建代理对象

RealSubject realSub = new RealSubject();

InvocationHandler handler = new DynamicSubject(realSub);

Class<?> classType = handler.getClass();

Subject sub = (Subject)Proxy.newProxyInstance(classType.getClassLoader(),

realSub.getClass().getInterfaces(), handler);

System.out.println(sub.getClass());        

5、通过调用代理对象的方法去调用真实角色的方法。

sub.Request();

输出:

class $Proxy0 新建的代理对象,它实现指定的接口

Method:public abstract void DynamicProxy.Subject.Request(),Args:null

RealSubject 调用的真实对象的方法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值