Java接口、lambda表达式与内部类——代理

推荐博文:https://blog.csdn.net/pangqiandou/article/details/52964066

利用代理可以在运行时创建一个实现了一组给定接口的新类

这种功能只有在编译时无法确定需要实现那个接口时才有必要使用

1.何时使用代理:

    假设有一个表示接口的Class对象(有可能只包含一个接口),它的确切类型在编译时无法知道。这确实有些难度。要想构造一个实现这些接口的类,就需要使用newInstance方法或反射找出这个类的构造器。但是,不能实例化一个接口,需要在程序处于运行状态是定义一个新类

    为了解决这个问题,有些程序将会生成代码;将这些代码放置在一个文件中;调用编译器;然后再加载结果类文件。这样做的速度会比较慢,并且需要将编译器与程序放在一起。

    代理机制则是一种更好的解决方案,代理类可以在运行时创建全新类。这样的代理类能够实现指定的接口,尤其是,它具有下列方法:

    1)指定接口中所需要的全部方法

    2)Object类中的全部方法

    不能再运行时定义这些方法的新代码,而是提供一个调用处理器

    调用处理器是实现了InvocationHandler接口的类对象,这个接口中只有一个方法:object invoke(Object proxy,Method method,Object[] args)

    无论何时调用代理对象分方法,调用处理器的invoke方法都会被调用,并向其传递Method对象和原始的调用参数。调用处理器必须给出处理调用的方式

2.创建代理对象:

    想要创建一个代理对象,需要使用Proxy类的newProxyInstance方法,这个方法有三个参数:

    1)一个类加载器

    2)一个Class对象数组

    3)一个调用处理器

3.代理类的特性:

    代理类是在程序运行过程中创建的。一旦被创建,就变成了常规类

    一个代理类只有一个实例域——调用处理器

    所有的代理类都覆盖了Object类中的方法toString、equals和hashCode,这些方法仅仅调用了调用处理器的invoke。Object中的其他方法没有被重定义(如clone和getClass)

    没有定义代理类的名字,sun虚拟机中的Proxy类将生成一个以字符串$Proxy开头的类名

    对于特定的类加载器和预设的一组接口来说,只能有一个代理类,也就是说,如果使用同一个类加载器和接口数组调用两次newProxyInstance方法的话,那么只能得到同一个类的两个对象,也可以利用getProxyClass方法获得这个类:

    Class proxyClass = Proxy.getProxyClass(null ,interfaces);

    代理类一定是public和final

    可以通过调用Proxy类中的isProxyClass方法检测一个特定的Class对象是否代表一个代理类

4.java.lang.reflect.InvocationHandler 1.3:

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

    定义了代理对象调用方法是希望执行的动作

5.java.lang.reflect.Proxy:

    static Class<?> getProxyClass(ClassLoader loader,Class<?>...interfaces)

    返回实现指定接口的代理类

    static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler handler)

    构造实现指定接口的代理类的一个新实例,所有方法会调用给定处理器对象的invoke方法

    static boolean isProxyClass(Class<?> cl)

    判断cl是否是一个代理类

猜你喜欢

转载自blog.csdn.net/qq_38386085/article/details/80833176