预期将“字符串"原始类型拆箱,但返回 null [英] Expected to unbox a 'String' primitive type but was returned null

查看:84
本文介绍了预期将“字符串"原始类型拆箱,但返回 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Java 反射来调用一个将回调作为参数的方法.我使用 Java 反射实例化所有对象.另外,我正在使用 Java 动态代理类 作为回调参数.

I am trying to use Java Reflection to call a method which takes a callback as an argument. I instantiate all of the objects with Java Reflection. Also, I am using a Java Dynamic Proxy Class as the callback argument.

我有一些奇怪的行为:

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

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

The following kinds of errors, depending on different versions I've tried of my code below:

  1. 期望对int"原始类型进行拆箱,但返回空值

期望对String"原始类型进行拆箱,但返回空值

这是我想实例化为匿名对象作为 Java 动态代理类的接口:

Here is the interface I want to instantiate as an anonymous object as a Java Dynamic Proxy Class:

public interface MyListener {
    void onEvent(String eventName);
}

这里是我如何通过 newProxyInstance() 实例化接口:

And here is how I instantiate the interface via 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 的日志消息似乎有冲突:

The log messages seem to conflict about whether callbackObject is null:

callbackObject=[null]
callbackObject is NOT null according to null check

根据 为什么 newInstance() 返回 null?newProxyInstance() 返回 null,因为它从 newInstance() 获取值.

According to Why does newInstance() return null? it's not possible for newProxyInstance() to return null because it gets the value from newInstance().

那么newProxyInstance()的结果怎么可能是null而不是null呢?以及诸如 Expected to unbox a 'int'基本类型但返回 null 之类的错误消息是什么意思?

So how can the result of newProxyInstance() be null and not null? And what do these error messages like Expected to unbox a 'int' primitive type but was returned null mean?

推荐答案

解决方案:java.lang.reflect.Proxy.newProxyInstance() 方法返回 null

Solution: java.lang.reflect.Proxy.newProxyInstance() method returns null

我发现 newProxyInstance() 返回的 Object not null,它只是看起来是 null>.打印出返回值的日志消息说它为空,因为 Java 隐式调用了对象上的 toString().但由于对象是一个 Proxy,它会被转发到我的 InvocationHandler.真正的问题是我的 InvocationHandler 总是返回 null.我认为 null 是合适的,因为 onEvent() 方法返回 void.然而,我没想到 toString() 也会被转发到 InvocationHandler.

I figured out the Object returned by newProxyInstance() is not null, it merely appears to be null. The log message that prints out the return value says it's null because Java implicitly calls toString() on the object. But since the object is a Proxy, it gets forwarded to my InvocationHandler. The real problem is with my InvocationHandler which always returns null. I thought null was suitable because the onEvent() method returns void. However, I didn't anticipate that toString() would also be forwarded to the InvocationHandler.

解决方案:希望对'int'原始类型进行拆箱,但返回null

在尝试调试明显的 null 时,我最终尝试对 newProxyInstance() 返回的对象调用其他方法,例如 hashcode()getClass().所有这些方法都被转发到了 InvocationHandler 中,它没有预料到它们,因此它只返回 null 的所有内容.由于 null 不是有效的 inthashcode() 函数导致错误 Expected to unbox a 'int' 原始类型但返回null.

While trying to debug the apparent null, I ended up trying to call other methods on the object returned by newProxyInstance(), for example hashcode() and getClass(). All of these methods get forwarded to the InvocationHandler which wasn't expecting them and so it just returned null for everything. Since null is not a valid int, the hashcode() function resulted in the error Expected to unbox a 'int' primitive type but was returned null.

通过使我的 InvocationHandler 更健壮一点,我能够消除这个错误:

I was able to eliminate this error by making my InvocationHandler a little more robust:

    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() 结果不是 <代码>空.并且在将来,请记住 InvocationHandler 会转发所有方法调用.

However, the actual solution for me was just to remove the debugging code that called hashcode(), etc. and trust that the newProxyInstance() result was not null. And in the future, keep in mind that the InvocationHandler gets forwarded all method calls.

感谢 artaxerxe 针对 Proxy 对象抛出 NullPointerException 的解决方案 给了我洞察力.

Thanks to artaxerxe's solution for Proxy object throws NullPointerException for giving me the insight.

这篇关于预期将“字符串"原始类型拆箱,但返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆