Java:反射
什么是反射?
反射允许对成员变量,成员方法和构造方法的信息进行编程访问
为了使用反射,首先要获取Class对象,才能剖析类中各种属性
获取方法Class对象的方法
1·Class.forName("全类名");
2·类名.class
3·对象.getClass();
Class类中用于获取构造方法的方法
利用class对象获取类中的构造方法(Constructor)
先获取类的编码对象
获取所有的public修饰的构造方法
获取所有的任意权限符修饰的构造方法
要特定获取某个构造方法就要在括号里面加上它的 参数类型的编码对象,顺序要一直
获取一个参数为int的构造方法,
获取一个参数为String的构造方法,
获取一个参数为String和int的构造方法
获取一个参数为空的构造方法
查看构造方法的权限修饰符con.getModifiers();
int modifiers = con4.getModifiers();返回的数值就是对应的修饰符
使用Construcor对象创建类的对象
诺是私有化修饰的构造方法则需要先跳过权限检查
Class类中用于获取成员变量的方法
利用class对象获取类中的成员变量(Field)
获取所有public修饰的成员变量
获取单个成员变量
获取单个成员变量非共有修饰的
获取成员变量的权限修饰符
通过Field获取成员变量的各种信息
通过Field修改某一个实例对象中成员变量里面的值
Class类中用于获取成员方法的方法
利用class对象获取类中的成员变量(Method)
获取所有的公共方法对象(包含父类中所有的公共方法)
获取所有的方法包含私有
获取特有的方法,第一个参数是方法名字,第二个参数是方法参数
获取方法的修饰符
获取方法中的其他信息
用Method类来进行方法运行
m获取的是Student类中的方法,用m调用invoke方法来运行
先创建一个实例,然后调用invoke方法,第一个参数是对象,第二个参数是方法里面的实际参数,
如果有返回值就要进行接受
动态代理
特点:无侵入式的给代码增加额外的功能
在Java中实现动态代理主要借助 java.lang.reflect.Proxy 类和 InvocationHandler 接口,下面通过一个简单的示例来详细说明实现步骤:
定义一个接口:被代理的类需要实现该接口,代理类也会实现这个接口。
// 定义一个接口
interface HelloService {
void sayHello();
}
实现接口的类(真实主题类):这是真正的业务逻辑实现类。
// 实现接口的类
class HelloServiceImpl implements HelloService {
@Override
public void sayHello() {
System.out.println("Hello, world!");
}
}
实现InvocationHandler接口:创建一个类实现 InvocationHandler 接口,并重写 invoke 方法,在 invoke 方法中编写代理的逻辑,包括在调用真实方法前后执行的操作。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
// 实现InvocationHandler接口
class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用真实方法前的逻辑");
Object result = method.invoke(target, args);
System.out.println("调用真实方法后的逻辑");
return result;
}
}
创建动态代理对象:使用 Proxy.newProxyInstance 方法来创建动态代理对象,该方法接收三个参数:被代理对象的类加载器、被代理对象实现的接口数组、 InvocationHandler 实例。
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
HelloService helloService = new HelloServiceImpl();
MyInvocationHandler handler = new MyInvocationHandler(helloService);
// 创建动态代理对象
HelloService proxy = (HelloService) Proxy.newProxyInstance(
helloService.getClass().getClassLoader(),
helloService.getClass().getInterfaces(),
handler);
proxy.sayHello();
}
}
在上述代码中, MyInvocationHandler 类实现了 InvocationHandler 接口, invoke 方法中添加了在调用真实方法前后执行的逻辑。通过 Proxy.newProxyInstance 方法创建了动态代理对象 proxy ,当调用 proxy.sayHello() 时,实际会调用 MyInvocationHandler 的 invoke 方法,并在其中调用真实对象的 sayHello 方法。