欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java通过代理创建Interface的匿名实现类 javaproxyinterface 

程序员文章站 2022-04-16 20:22:34
...

昨天帮同事看问题的时候碰到的, 简要描述一下实现.

 

需求:

Java下反射获取Interface, 实例化它并同时实现其中的方法.

 

实现: 

反射一个类好说, 从类名拿到Class再newInstance一把就有, 方法什么的, 也是Method.invoke一下就行.

但是反射一个Interface, 以前没碰到过, 同事听别人说要用代理实现, 于是百度后试了一把, 果然可以.

 

反射这个Interface:

package com.test.util;
public interface TestInterface {
    public int getInt();
}

 

 

1. 先要拿到ClassLoader和Interface(以com.test.util.TestInterface为例), 后者不需要实例化, 当然也不能够实例化:

ClassLoader loader = InterfaceProxy.class.getClassLoader();
Class interfazz = loader.loadClass("com.test.util.TestInterface");

 2. 然后就是通过Proxy拿到Interface实例, 同时实现其中的方法:

Object clazzInstance = Proxy.newProxyInstance(loader, new Class[] { interfazz }, new InvocationHandler() {

    @Override
    public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
        if (method.getName().equals("getInt")) {
            return 1234;
        } else {
            return method.invoke(obj, args);
        }
    }
});

 3. 拿到了实例, 就能调用了, 调用的时候当然是通过反射:

Method method = clazzInstance.getClass().getMethod("getInt", new Class[] {});
System.out.println("getInt = " + (int) method.invoke(clazzInstance, new Class[] {}));

 4. 可以看到输出的log是:

getInt = 1234

 

需求的逻辑就这样通了~~~~~

 

======================== 纯纯的分隔线 ========================

 

这部分还能扩展一下, 注意Proxy.newProxyInstance方法的第二个参数. 该参数是一个Class数组, 即具备"实例化一个实现了多个Interface的匿名类"的能力. 在实现多个Interface后, 可以在invoke方法下根据方法名 & 参数来实现指定的方法.

另外, 这里面还有一个值得注意的地方, 就是实现这些Interface时, 不需要实现所有方法, 因此在实现类下未实现的方法被调用时, 会crash.