Java 为什么 int num = Integer.getInteger("123") 抛出 NullPointerException?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3123349/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does int num = Integer.getInteger("123") throw NullPointerException?
提问by user282886
The following code throws NullPointerException
:
以下代码抛出NullPointerException
:
int num = Integer.getInteger("123");
Is my compiler invoking getInteger
on null since it's static? That doesn't make any sense!
我的编译器是否调用getInteger
null 因为它是静态的?那没有任何意义!
What's happening?
发生了什么?
采纳答案by polygenelubricants
The Big Picture
大图
There are two issues at play here:
这里有两个问题在起作用:
Integer getInteger(String)
doesn't do what you think it does- It returns
null
in this case
- It returns
- the assignment from
Integer
toint
causes auto-unboxing- Since the
Integer
isnull
,NullPointerException
is thrown
- Since the
Integer getInteger(String)
不会做你认为它会做的事null
在这种情况下它返回
- 分配 from
Integer
toint
导致自动拆箱- 由于
Integer
是null
,NullPointerException
被抛出
- 由于
To parse (String) "123"
to (int) 123
, you can use e.g. int Integer.parseInt(String)
.
要解析(String) "123"
为(int) 123
,您可以使用例如int Integer.parseInt(String)
。
References
参考
Integer
API references
Integer
API 参考
On Integer.getInteger
在 Integer.getInteger
Here's what the documentation have to say about what this method does:
以下是文档对这种方法的作用的说明:
public static Integer getInteger(String nm)
: Determines the integer value of the system property with the specified name. If there is no property with the specified name, if the specified name is empty ornull
, or if the property does not have the correct numeric format, thennull
is returned.
public static Integer getInteger(String nm)
:确定具有指定名称的系统属性的整数值。如果没有具有指定名称的属性,如果指定的名称为空或null
,或者如果属性没有正确的数字格式,则null
返回 。
In other words, this method has nothing to do with parsing a String
to an int/Integer
value, but rather, it has to do with System.getProperty
method.
换句话说,该方法与将 a 解析String
为int/Integer
值无关,而是与System.getProperty
方法有关。
Admittedly this can be quite a surprise. It's unfortunate that the library has surprises like this, but it does teach you a valuable lesson: always look up the documentation to confirm what a method does.
诚然,这可能是一个惊喜。不幸的是,图书馆有这样的惊喜,但它确实教会了你一个宝贵的教训:总是查阅文档以确认方法的作用。
Coincindentally, a variation of this problem was featured in Return of the Puzzlers: Schlock and Awe (TS-5186), Josh Bloch and Neal Gafter's 2009 JavaOne Technical Session presentation. Here's the concluding slide:
巧合的是,这个问题的一个变体出现在谜题归来:Schlock 和 Awe (TS-5186)、Josh Bloch 和 Neal Gafter 的 2009 年 JavaOne 技术会议演示中。这是最后的幻灯片:
The Moral
- Strange and terrible methods lurk in libraries
- Some have innocuous sounding names
- If your code misbehaves
- Make sure you're calling the right methods
- Read the library documentation
- For API designers
- Don't violate the principle of least astonishment
- Don't violate the abstraction hierarchy
- Don't use similar names for wildly different behaviors
道德
- 图书馆中潜伏着奇怪而可怕的方法
- 有些名字听起来无害
- 如果您的代码行为不当
- 确保你调用了正确的方法
- 阅读库文档
- 对于 API 设计人员
- 不要违反最小惊讶原则
- 不要违反抽象层次结构
- 不要为截然不同的行为使用相似的名称
For completeness, there are also these methods that are analogous to Integer.getInteger
:
为了完整起见,还有这些方法类似于Integer.getInteger
:
Related questions
相关问题
- Most Astonishing Violation of the Principle of Least Astonishment
- Most awkward/misleading method in Java Base API ?
On autounboxing
关于自动拆箱
The other issue, of course, is how the NullPointerException
gets thrown. To focus on this issue, we can simplify the snippet as follows:
当然,另一个问题是如何NullPointerException
抛出。为了关注这个问题,我们可以将代码片段简化如下:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Here's a quote from Effective Java 2nd Edition, Item 49: Prefer primitive types to boxed primitives:
这里引用自 Effective Java 2nd Edition,Item 49:Prefer prime types to boxed primes:
In summary, use primitives in preference to boxed primitive whenever you have the choice. Primitive types are simpler and faster. If you must use boxed primitives, be careful! Autoboxing reduces the verbosity, but not the danger, of using boxed primitives. When your program compares two boxed primitives with the
==
operator, it does an identity comparison, which is almost certainly not what you want. When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throwNullPointerException
. Finally, when your program boxes primitive values, it can result in costly and unnecessary object creations.
总之,只要您有选择,就优先使用原语而不是盒装原语。原始类型更简单、更快。如果您必须使用盒装原语,请小心!自动装箱减少了使用装箱原语的冗长性,但没有减少危险。当您的程序将两个装箱原语与
==
运算符进行比较时,它会进行身份比较,这几乎肯定不是您想要的。当您的程序进行涉及装箱和未装箱原语的混合类型计算时,它会进行拆箱,而当您的程序进行拆箱时,它会抛出NullPointerException
. 最后,当您的程序装箱原始值时,可能会导致成本高昂且不必要的对象创建。
There are places where you have no choice but to use boxed primitives, e.g. generics, but otherwise you should seriously consider if a decision to use boxed primitives is justified.
有些地方您别无选择,只能使用装箱原语,例如泛型,但除此之外,您应该认真考虑使用装箱原语的决定是否合理。
Related questions
相关问题
- What is the difference between an int and an Integer in Java/C#?
- Why does autoboxing in Java allow me to have 3 possible values for a boolean?
- Is it guaranteed that new Integer(i) == i in Java?(YES!!!)
- When comparing two Integers in Java does auto-unboxing occur? (NO!!!)
- Java noob: generics over objects only?(yes, unfortunately)
回答by Kieren Johnstone
From http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html:
来自http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html:
getInteger 'Determines the integer value of the system property with the specified name.'
getInteger '确定具有指定名称的系统属性的整数值。
You want this:
你要这个:
Integer.parseInt("123")
回答by Sonal Patil
Please check documentation of the method getInteger().
In this method, the String
parameter is a system property that determines the integer value of the system property with the specified name. "123" is not the name of any system property, as discussed here.
If you want to convert this String to int
, then use the method as
int num = Integer.parseInt("123")
.
请检查getInteger()方法的文档。在此方法中,String
参数是一个系统属性,它确定具有指定名称的系统属性的整数值。正如此处所讨论的,“123”不是任何系统属性的名称。如果要将此 String 转换为int
,则使用方法 as
int num = Integer.parseInt("123")
。