1

在 Java 中,我可以执行以下操作来简洁地防范 a NullPointerException

if ("myString".equals(someOtherString))

但我不能对整数做同样的事情,例如

if (5.equals(someOtherInteger))

我得到一个编译时错误。关于为什么做出这个设计决定的任何想法?或者任何可以解释它的资源?提前致谢。

编辑someOtherInteger是一个Integer,不是一个int

4

6 回答 6

13

String在Java中一直是一个对象。字符串没有自动装箱,原则上也不可能。最近引入了从基元int到对象的自动装箱。Integer

问一下为什么尝试访问基元的成员变量不会调用自动装箱是有效的(95.toString(radix)实际上会很方便),但我想原因是它不被认为是一个可能的用例,因为几乎每个wrappedPrimitive.method()都有等效WrapperClass.method( primitive )版本。

equals()对于原始类型通常是不必要的,因为==它已经存在。但是,您确实为它提供了一个很好的案例作为 null-guard...5 == integerInstance将尝试拆箱实例,NullPointerException如果实例是,则抛出 a null,不幸的是。(一开始我并没有完全理解你的观点。)

也就是说,如果我们能听到目前或在引入自动装箱时从事 Java 工作的人关于他们是否考虑过这种功能,那将是非常酷的。

于 2012-04-17T03:34:39.280 回答
10

JLS指定装箱转换只能在赋值转换、方法调用转换或强制转换期间发生。由于您既没有分配5给变量,也没有将其作为参数传递给方法,也没有显式地将其强制转换为Integer,因此不会为您自动装箱。

赋值转换(第 5.2 节、第 15.26 节)将表达式的类型转换为指定变量的类型。

赋值转换可能会导致 OutOfMemoryError(由于装箱转换(第 5.1.7 节))、NullPointerException(由于取消装箱转换(第 5.1.8 节))或 ClassCastException(由于未经检查的转换( §5.1.9)) 在运行时抛出。

方法调用转换(第 5.3 节、第 15.9 节、第 15.12 节)应用于方法或构造函数调用中的每个参数,并且除了在一种情况下,执行与赋值转换相同的转换。

方法调用转换可能会导致 OutOfMemoryError(作为装箱转换的结果(第 5.1.7 节))、NullPointerException(作为取消装箱转换的结果(第 5.1.8 节))或 ClassCastException(作为未经检查的转换的结果) (§5.1.9)) 在运行时抛出。


强制转换上下文允许使用以下之一:

...

装箱转换(§5.1.7)可选地后跟扩大参考转换(§5.1.5)

于 2012-04-17T03:43:13.940 回答
1

您可以使用

if (someOtherInteger!=null && someOtherInteger == 5)
于 2012-04-17T03:26:39.847 回答
1

我怀疑 autoboxing 没有为 literal 实现5,而它是为 string 实现的myString,作为一种安全措施。自动装箱一个带有双引号的句法结构是安全的"",因为引号不太可能是无意的,因此用户的意图很明确并且不会损害类型安全。

但是,文字5可能是用户的拼写错误——或者它可能是一个字符串,而不是一个整数。因此,为了保持在面向对象编程中使用之前必须声明变量以防止拼写错误(以及许多其他优点)(即使它是隐式的,如自动装箱)5的好处,不会自动装箱。

于 2012-04-17T03:39:33.877 回答
0

int是一种原始类型,它本身不支持任何方法。要比较 2 ints,您只需使用以下==约定:

if(a == b) 

有一个Integer类是一个int支持一些其他方法调用的包装器

编辑:

根据您要比较的编辑,Integer但问题是文字 5 不是Integer您必须为其创建一个新整数。

Integer myInt = 5;
if(myInt.equals(someOtherInteger)) ...

这种设计是由于原语没有任何方法这一事实所固有的。至于原语是否应该支持方法(或根本不存在)是关于 Java 是否是纯面向对象语言的争论的组成部分(由于原语存在这一事实,许多人说不)。

于 2012-04-17T03:28:14.933 回答
0

以下是关于不同比较的一些阅读:http: //www.leepoint.net/notes-java/data/expressions/22compareobjects.html

不确定是否是内置设计拒绝int

如果你这样做

Integer s=5;
Integer d=5;
if(d.equals(s)){
    System.out.println("Fun");
}

它工作得很好。

于 2012-04-17T03:31:08.210 回答