【问题标题】:How to tell if a primitive type was cast into an object in Java?如何判断原始类型是否被转换为 Java 中的对象?
【发布时间】:2017-10-14 18:09:46
【问题描述】:

在 Java 中,考虑以下代码:

int myPrimitiveInt = 5;
Integer myObjectInt = 4;

Object fromPrimitive = myPrimitiveInt;
Object fromObject = myObjectInt;

System.out.println(fromPrimitive.getClass());
System.out.println(fromObject.getClass());
System.out.println(int.class);

还有输出:

class java.lang.Integer
class java.lang.Integer
int

我想要的是一种同时为第一个 println 获取输出 int 的方法。


为什么?,你会问。好吧,一方面,我想知道这样的事情是否可行。

但这背后的实际原因是一个抽象层,用于通过反射测试带有原始类型参数的私有方法。最小代码:

package testing;

import java.lang.reflect.Method;

public class Testing {
    private static void doStuff(int a) {
        System.out.println("primitive: " + ((Object) a).getClass());
    }

    public static void main(String[] args) throws ReflectiveOperationException {
        Reflect.reflect(Testing.class, "doStuff", 10);
    }
}

abstract class Reflect {
    static Object reflect(Class<?> clazz, String methodName, Object arg) throws ReflectiveOperationException {
        Method method = clazz.getDeclaredMethod(methodName, arg.getClass());
        method.setAccessible(true);
        return method.invoke(null, arg);
    }
}

输出:

Exception in thread "main" java.lang.NoSuchMethodException: testing.Testing.doStuff(java.lang.Integer)
at java.lang.Class.getDeclaredMethod(Class.java:2130)
at testing.Reflect.reflect(Testing.java:17)
at testing.Testing.main(Testing.java:11)

预期输出:

primitive: class java.lang.Integer

甚至更好(如果可能的话):

primitive: int

注意:我知道我可以做到clazz.getDeclaredMethod(methodName, int.class)。这篇文章的重点是使这个过程更加抽象。请不要给我建议将参数 types 传递给 reflect 方法的答案!

【问题讨论】:

  • 原始类型不能转换为 Object。它们将始终被装箱,然后您就无法分辨出产地是什么。对于Integer,第一个来源始终是原始类型
  • 不可能。在您的示例中,5 和 4 都经历了相同的自动装箱过程;一个只是稍后自动装箱。
  • 不,你不能。您将原语强制放入一个对象中,因此它被装箱了。这会创建一个 Integer 的实例。
  • 你不能。因此,一些类有许多重载方法,除了处理 Object 之外,它们还会处理原始类型(以避免装箱)。

标签: java reflection casting overloading primitive


【解决方案1】:

当你写Object x = 10时会发生什么

intautoboxed,这使它成为一个值为 10 的 Integer

为什么事后检测不到

因为自动装箱的值为 10 的 Integer 与另一个值为 10 的 Integer 之间没有区别

我该如何解决这个问题

您需要添加单独的方法来重载原始值,这些方法可以处理原始值,因此它们不会被自动装箱。

【讨论】:

  • 谢谢,我想我会为这些原语做一个解决方法。
【解决方案2】:

原始类型永远不会“强制转换”为对象。

原语可以“自动装箱”到对象中,但您永远无法在代码中确定这一点,因为自动装箱只是编译器添加的代码,与您可能手动添加的相同代码没有区别。

【讨论】:

    猜你喜欢
    • 2010-09-17
    • 2015-12-19
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多