昨天帮同事看问题的时候碰到的, 简要描述一下实现.
?
需求:
Java下反射获取Interface, 实例化它并同时实现其中的方法.
?
实现:?
反射一个类好说, 从类名拿到Class再newInstance一把就有, 方法什么的, 也是Method.invoke一下就行.
但是反射一个Interface, 以前没碰到过, 同事听别人说要用代理实现, 于是百度后试了一把, 果然可以.
?
反射这个Interface:
class="java" name="code">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
?
需求的逻辑就这样通了~~~~~
?
======================== 纯纯的分隔线?========================
?
这部分还能扩展一下, 注意monospace; line-height: 1.5; background-color: #fafafa;">Proxy.newProxyInstance方法的第二个参数. 该参数是一个Class数组, 即具备"实例化一个实现了多个Interface的匿名类"的能力. 在实现多个Interface后, 可以在invoke方法下根据方法名 & 参数来实现指定的方法.
另外, 这里面还有一个值得注意的地方, 就是实现这些Interface时, 不需要实现所有方法, 因此在实现类下未实现的方法被调用时, 会crash.