我正在尝试使用Java Reflection来调用将回调作为参数的方法。我使用Java Reflection实例化所有对象。另外,我使用Java Dynamic Proxy Class作为回调参数。
我有几种奇怪的行为:
java.lang.reflect.Proxy.newProxyInstance()
方法返回null
以下几种错误,具体取决于我尝试的以下代码版本:
Expected to unbox a 'int' primitive type but was returned null
Expected to unbox a 'String' primitive type but was returned null
这是我想实例化为Java动态代理类的匿名对象的接口:
public interface MyListener {
void onEvent(String eventName);
}
这是我如何通过newProxyInstance()
实例化接口的方法:
Object callbackObject = null;
try {
Class callbackClass = Class.forName("com.example.MyListener");
Class[] interfaceArray = new Class[]{callbackClass};
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("onMyEvent")) {
Log.d(TAG, "InvocationHandler.invoke onMyEvent");
}
return null;
}
};
callbackObject = java.lang.reflect.Proxy.newProxyInstance(
this.getClass().getClassLoader(),
interfaceArray,
invocationHandler);
}
catch (Throwable t) {
Log.e(TAG, "newProxyInstance got exception [" + t + "] caused by [" + t.getCause() + "]");
}
Log.d(TAG, "callbackObject=[" + callbackObject + "]");
if (null == callbackObject) {
Log.e(TAG, "callbackObject is null according to null check");
}
else {
Log.d(TAG, "callbackObject is NOT null according to null check");
}
关于callbackObject是否为null的日志消息似乎冲突:
callbackObject=[null]
callbackObject is NOT null according to null check
根据Why does newInstance() return null?,newProxyInstance()
不可能返回null,因为它从newInstance()
获取值。
那么newProxyInstance()
的结果如何是null
而不是null
?这些错误消息,例如Expected to unbox a 'int' primitive type but was returned null
是什么意思?
答案 0 :(得分:0)
解决方案:java.lang.reflect.Proxy.newProxyInstance()
方法返回null
我发现newProxyInstance()
返回的对象不是 null
,它似乎只是null
。打印出返回值的日志消息说它为null,因为Java隐式调用对象上的toString()
。但是由于该对象是Proxy
,因此它将转发到我的InvocationHandler
。真正的问题是我的InvocationHandler
总是返回null
。我认为null
是合适的,因为onEvent()
方法返回void
。但是,我没想到toString()
也将转发到InvocationHandler
。
解决方案:Expected to unbox a 'int' primitive type but was returned null
在尝试调试明显的null
时,我最终尝试在newProxyInstance()
返回的对象上调用其他方法,例如hashcode()
和getClass()
。所有这些方法的所有都转发到了InvocationHandler
,因为它们并没有期望它们,因此它只返回了null
的所有内容。由于null
不是有效的int
,因此hashcode()
函数导致错误Expected to unbox a 'int' primitive type but was returned null
。
通过使我的InvocationHandler
更加健壮,我可以消除此错误:
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("onMyEvent")) {
Log.d(TAG, "InvocationHandler.invoke onMyEvent");
return null;
}
else if (String.class == method.getReturnType()) {
return "";
}
else if (Integer.class == method.getReturnType()) {
return Integer.valueOf(0);
}
else if (int.class == method.getReturnType()) {
return 0;
}
else if (Boolean.class == method.getReturnType()) {
return Boolean.FALSE;
}
else if (boolean.class == method.getReturnType()) {
return false;
}
else {
return null;
}
}
};
但是,对我来说,实际的解决方案是删除称为hashcode()
等的调试代码,并相信newProxyInstance()
的结果不是null
。而且将来,请记住InvocationHandler
会转发所有方法调用。
感谢artaxerxe's solution for Proxy object throws NullPointerException为我提供了见识。