我正在准备面试,当我经历空指针异常时,我突然意识到每个对象都能够以某种方式抛出空指针异常,但我似乎无法想象 System、Out 等某些对象会抛出NullPointerException
. 谁能提到这样的场景?谢谢!
例如:System.out.println(s.get(name));
我正在准备面试,当我经历空指针异常时,我突然意识到每个对象都能够以某种方式抛出空指针异常,但我似乎无法想象 System、Out 等某些对象会抛出NullPointerException
. 谁能提到这样的场景?谢谢!
例如:System.out.println(s.get(name));
首先,System
不是一个对象。它是一个方法是静态的类。其次,out
是该类的静态字段,它(最初)是对标准输出的引用PrintStream
。您可以使用 将其更改PrintStream
为您自己的System.setOut(PrintStream)
。
最后,如果你这样做了
System.setOut(null);
System.out.println("42"); // because out is now a null reference
你会得到一个NullPointerException
.
当然,你也可以找到一个System
抛出 a的方法NullPointerException
。
NullPointerException
当您尝试取消引用null
对象引用时,大多数这些都是由 JVM 抛出的。
你不取消引用一个类。
只有可执行代码可以抛出 NPE,例如方法、构造函数或初始化程序。- 马尔科
并非每个对象都能够抛出 NullPointerException。通常最好尝试编写不能写的类!
public class ClassThatCannotNPE {
public int getOne() {
return 1;
}
}
您可以对上述类做的唯一两件事是运行其构造函数并调用 getOne()。这些东西都不能NPE。
我们必须小心地定义我们所说的“某事”引发异常的意思。此代码将在第 2 行抛出 NPE:
Date d = null;
System.setProperty("now",d.toString());
但这不是 System 或 System 中的代码抛出异常的示例。上面的代码等价于:
Date d = null;
String temp = d.toString();
System.setProperty(temp);
这也会在第 2 行抛出 NPE——在 System.setProperty() 有机会运行之前。执行顺序与前面的示例完全相同。
关于什么:
System.out.print(null);
这将引发 NPE。但是再一次,抛出它的不是 System 的代码。它相当于:
PrintStream temp = System.out;
temp.print(null);
NPE 发生在第 2 行——它既不是指 System,也不是指任何指 System.
System
是一个类,而不是一个对象。它没有构造函数,因此无法实例化。
但是,它有很多静态方法。是否有可能让其中任何一个抛出 NullPointerException?
实际上,通过查看System 的 Javadoc并搜索“NullPointerException” ,我们可以很快找到答案。许多人的第一场比赛是在System.arraycopy():
如果 dest 为 null,则抛出 NullPointerException。
所以你有它:
System.arrayCopy(null,0,null,0,0);
... 会导致 System 类中的一些代码抛出 NPE。
事实上,我们可以查看System 的实际源代码,看看它在哪里抛出 NullPointerExceptions。
488 public static native void arraycopy(Object src, int srcPos,
489 Object dest, int destPos,
490 int length);
哦。arraycopy 是本机的——这意味着实际的实现是 JRE 中的一些 C 代码。但我们还能找到什么?
825 private static void checkKey(String key) {
826 if (key == null) {
827 throw new NullPointerException("key can't be null");
828 }
...
和
777 public static String setProperty(String key, String value) {
778 checkKey(key);
...
因此,使 System 中的代码抛出 NPE 的另一种方法是:
System.setProperty(null,"value");
对null
对象的操作将抛出NullPointerException
. 在示例中s.get(name)
e if s
is null
then aNullPointerException
将被抛出。因为System
是class
,所以静态引用不会为空。查看源代码,您可以看到它out
是静态的,final
并且最终使用以下命令进行初始化。
setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
通常,因为它是final
这意味着它不会null
也不能制造null
。但是public static void setOut(PrintStream out)
调用一个本机函数private static native void setOut0(PrintStream out)
,实现 VM 可以在其中创建一个空引用。
这取决于方法的实现是否会抛出NullPointerException
. 具体来说println(String)
,在对传入的变量进行操作之前会进行一次空检查。
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
NullPointerException
因此,在这种情况下,只要PrintStream
正确初始化方法本身就不应抛出 a在这种情况下System
。
我希望这有助于回答你的问题。如果没有,请在评论中阐明您在寻找什么。
Wrapper 类能够抛出 NPE。尽管 java 提供了自动装箱,但与原始数据类型不同,它们默认情况下不会初始化。
Integer r;
if(r>1)