在Java中,我可以执行以下操作以简洁地防范NullPointerException
:
if ("myString".equals(someOtherString))
但我不能对整数做同样的事,例如
if (5.equals(someOtherInteger))
我遇到编译时错误。有关为何做出此设计决定的任何想法?或者任何可能解释它的资源?提前谢谢。
编辑:someOtherInteger
是Integer
,而不是int
。
答案 0 :(得分:12)
String
一直是Java中的一个对象。字符串没有自动装箱,原则上不存在。最近引入了从原始int
到Integer
对象的自动装箱。
有问题为什么尝试访问基元的成员变量不会调用自动装箱(95.toString(radix)
实际上会非常方便),但我想原因是它不被认为是可能的用途-case,因为几乎每个wrappedPrimitive.method()
都有一个等效的WrapperClass.method( primitive )
版本。
equals()
已存在,原始类型通常不需要 ==
。但是,您确实为它做了一个很好的案例作为空值保护... 5 == integerInstance
将尝试取消装箱实例,并且如果实例为NullPointerException
则抛出null
,不幸的是。 (起初我并不完全理解你的观点。)
也就是说,如果我们能够听到目前从事Java工作的人或在引入自动装箱时听到他们是否考虑过这种功能,那将会非常酷。
答案 1 :(得分:10)
JLS指定装箱转换只能在分配转化,方法调用转换或转换转换期间进行。由于您既未将5
分配给变量,也未将其作为参数传递给方法,也未将其明确地转换为Integer
,因此不会为您自动生成。
分配转换(§5.2,§15.26)转换a的类型 表达式为指定变量的类型。
分配转换可能会导致OutOfMemoryError(因此而导致) 拳击转换(§5.1.7)),一个NullPointerException(作为结果 拆箱转换(§5.1.8))或ClassCastException(作为结果 在运行时抛出未经检查的转换(第5.1.9节)。
方法调用转换(第5.3节,第15.9节,第15.12节)适用于每个 方法或构造函数调用中的参数,除了一个 case,执行与分配转换相同的转换。
方法调用转换可能会导致OutOfMemoryError(作为 拳击转换的结果(§5.1.7)),一个NullPointerException(作为 取消装箱转换(第5.1.8节)的结果,或ClassCastException(作为 在运行时抛出未经检查的转换(第5.1.9节)的结果。
投射上下文允许使用以下之一:
...
拳击转换(§5.1.7),可选地后跟加宽 参考转换(第5.1.5节)
答案 2 :(得分:1)
你可以使用
if (someOtherInteger!=null && someOtherInteger == 5)
答案 3 :(得分:1)
我怀疑文字5
没有实现自动装箱,而是作为安全措施的字符串myString
。自动放置一个前缀并附加双引号""
的句法结构是安全的,因为引号不太可能是无意的,因此用户的意图是明确的,并且不会损害类型安全性。
然而,文字5
可能是用户的一个错字 - 或者它可能是一个字符串,而不是一个整数。因此,为了防止在使用面向对象编程之前必须声明变量以防止打字错误(以及许多其他优点)(即使它是隐含的,如在自动装箱的情况下),5
不是autoboxed。
答案 4 :(得分:0)
int
是一种原始类型,它本身不支持任何方法。要比较2 ints
,您只需使用==
约定,如下所示:
if(a == b)
有一个Integer
类是int
的包装器,支持其他一些方法调用
编辑:
根据您想要与Integer
进行比较的编辑,但问题是文字5不是Integer
,您必须为其创建新的整数。
Integer myInt = 5;
if(myInt.equals(someOtherInteger)) ...
这种设计是基元没有任何方法的事实。至于原语是否应该支持方法(或根本不存在)是关于Java是否是纯面向对象语言的辩论不可或缺的(许多人说由于存在原语这一事实而没有)。
答案 5 :(得分: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");
}
它运作得很好。