[英]Java Reflection: Call method from Interface name
我有一個接口的名稱,我想調用由其具體實現的類定義的方法。 因此,我接受了Java Reflection的幫助。
界面:
package tsb.learning.reflection;
public interface IAnyThing {
void doSomething();
}
它是實現的類:
package tsb.learning.reflection;
public class AnyThing implements IAnyThing {
public void doSomething() {
System.out.println("JYM");
}
}
InvocationHandler
的實現:
package tsb.learning.reflection;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class AnyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(proxy, args);
}
}
和控制器:
package tsb.learning.reflection;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Controller {
/**
* @param args
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws ClassNotFoundException {
String interfaceName = "tsb.learning.reflection.IAnyThing";
ClassLoader classLoader = Class.forName(interfaceName).getClassLoader();
Class<?>[] interfaces = new Class<?>[] { Class.forName(interfaceName) };
InvocationHandler handler = new AnyInvocationHandler();
IAnyThing anyThing = (IAnyThing) Proxy.newProxyInstance(classLoader, interfaces, handler);
anyThing.doSomething();
}
}
但這不起作用,並且出現以下異常:
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at tsb.learning.reflection.AnyInvocationHandler.invoke(AnyInvocationHandler.java:10)
at $Proxy0.doSomething(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at tsb.learning.reflection.AnyInvocationHandler.invoke(AnyInvocationHandler.java:10)
at $Proxy0.doSomething(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at tsb.learning.reflection.AnyInvocationHandler.invoke(AnyInvocationHandler.java:10)
at $Proxy0.doSomething(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at tsb.learning.reflection.AnyInvocationHandler.invoke(AnyInvocationHandler.java:10)
例外是在控制台循環打印,我需要停止程序。
任何信息對我都會非常有幫助。
造成原因:java.lang.reflect.InvocationTargetException
這意味着您調用的方法引發了異常。 您需要查看在它之后出現的異常並引起該異常。 它與您如何調用該方法無關。
我懷疑您收到了StackOverflowError
// calls the same method on the same proxy which will recurse until you get an error.
return method.invoke(proxy, args);
而是嘗試在實際對象上調用方法以執行某些操作。
public class AnyInvocationHandler implements InvocationHandler {
final IAnyThing iat;
public AnyInvocationHandler(IAnyThing iat) {
this.iat = iat;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// call the same method on a real object.
return method.invoke(iat, args);
}
}
順便說一句你可以寫
Class interfaceClass = tsb.learning.reflection.IAnyThing.class;
ClassLoader classLoader = interfaceClass.getClassLoader();
Class<?>[] interfaces = new Class<?>[] { interfaceClass };
在AnyInvocationHandler
內部,您可以將調用委派給AnyThing
的實例:
public class AnyInvocationHandler implements InvocationHandler {
private AnyThing delegate = new AnyThing();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// to something useful here
[...]
// finally, invoke the method on implementation class.
return method.invoke(delegate, args);
}
}
IAnyThing
唯一的方法是doSomething()
,所以我猜在InvocationHandler
您知道該方法是什么。 只需將您的實現放在這里。 另外,除了doSomething()
您還應該處理從java.lang.Object
繼承的三個方法:
public static class AnyInvocationHandler implements InvocationHandler {
private static final Method doSomething;
static {
try {
doSomething = IAnyThing.class.getMethod("doSomething");
} catch (NoSuchMethodException e) {
throw new ExceptionInInitializerError(e);
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getDeclaringClass() == Object.class)
return handleObjectMethod(proxy, method, args);
if (doSomething.equals(method)) {
doSomethingImpl();
return null;
}
throw new AbstractMethodError(method.toString());
}
private Object handleObjectMethod(Object proxy, Method method, Object[] args) {
switch (method.getName()) {
case "equals":
return proxy == args[0];
case "hashCode":
return System.identityHashCode(proxy);
case "toString":
return proxy.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(proxy));
default:
throw new AssertionError();
}
}
private void doSomethingImpl() {
// implement....
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.