【问题标题】:Expected to unbox a 'String' primitive type but was returned null应拆箱“字符串”原始类型,但返回 null
【发布时间】:2018-09-15 01:42:46
【问题描述】:

我正在尝试使用 Java 反射来调用将回调作为参数的方法。我使用 Java 反射实例化所有对象。另外,我使用Java Dynamic Proxy Class 作为回调参数。

我有几个奇怪的行为:

  1. java.lang.reflect.Proxy.newProxyInstance()方法返回null

  2. 以下类型的错误,取决于我尝试过的以下代码的不同版本:

    1. Expected to unbox a 'int' primitive type but was returned null

    2. 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 这样的错误消息是什么意思?

【问题讨论】:

    标签: java android reflection


    【解决方案1】:

    解决方案: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 不是有效的inthashcode() 函数导致错误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 给予我见解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2018-07-24
      • 2021-09-18
      • 2013-11-29
      相关资源
      最近更新 更多