我来自 c++ 背景,我发现自己经常在 java 中这样做:
SomeClass sc=new SomeClass();
if(null!=sc)
{
sc.doSomething();
}
我想知道的是,如果构造函数由于某种原因失败(比如可能没有足够的内存),变量 sc 中的内容是什么。我找不到一个直接的答案,我担心我只是在浪费我的时间,因为如果新的操作员失败了,程序是否会崩溃?
我来自 c++ 背景,我发现自己经常在 java 中这样做:
SomeClass sc=new SomeClass();
if(null!=sc)
{
sc.doSomething();
}
我想知道的是,如果构造函数由于某种原因失败(比如可能没有足够的内存),变量 sc 中的内容是什么。我找不到一个直接的答案,我担心我只是在浪费我的时间,因为如果新的操作员失败了,程序是否会崩溃?
Java Specification Language 3rd Edition彻底涵盖了您的问题:
12.5 新类实例的创建
每当创建一个新的类实例时,都会为其分配内存空间,并为该类类型中声明的所有实例变量和该类类型的每个超类中声明的所有实例变量(包括所有可能隐藏的实例变量)分配空间。如果没有足够的可用空间为对象分配内存,则类实例的创建会以
OutOfMemoryError
. 否则,新对象中的所有实例变量,包括在超类中声明的变量,都将初始化为其默认值。就在作为结果返回对新创建对象的引用之前,使用以下过程处理指示的构造函数以初始化新对象:[...]
new
因此,表达式根本不可能return null
。无论返回什么,如果执行正常完成,将始终是一个有效的instanceof
任何类被实例化。
一般来说,可能的异常通常用try-catch
块来处理:
String someString = askFromUser();
try {
int num = Integer.parseInt(someString);
doSomethingWith(num);
} catch (NumberFormatException e) {
complainAboutIt();
}
在您的情况下,您可以考虑放入new SomeClass()
一个try
带有相应 的块catch (OutOfMemoryError e)
,但这是非常不典型的。除非您打算在发生这种情况时做一些有意义的事情,否则在大多数典型情况下,最好不要在程序执行期间发生catch
任何Error
可能发生的事情。
从文档中:
An
Error
是一个子类,Throwable
它表示一个合理的应用程序不应该出现的严重try
问题catch
。大多数此类错误是异常情况。方法不需要在其子句中声明在方法执行期间可能抛出但未被捕获的
throws
任何子类,因为这些错误是不应该发生的异常情况。Error
如果构造函数失败,那么它将抛出异常或错误,并且您将无法在程序中获得任何进一步的信息。具体来说,如果内存不足,您会得到一个OutOfMemoryError
.
SomeClass sc=new SomeClass();
if(null!=sc) { sc.doSomething(); }
对象引用永远不会null
在创建对象之后进行,因此不需要进行空检查,因为条件始终为真。
例如,如果构造函数中的该点没有足够的内存,OutOfMemoryError
则会抛出 an 并且构造函数将无法正常返回。
是的,你在浪费时间:-)。调用构造函数后,sc 保证为非空。如果构造函数失败,则会抛出异常,并且永远不会运行以下代码。因此,以下在 Java 中是安全的:
SomeClass sc = new SomeClass();
sc.doSomething();
不抛出 NullPointerException。
该if
检查不是必需的,一些 IDE 甚至会抱怨它是不必要的,因为它总是评估为true
. 失败的唯一原因new
是构造函数抛出异常,在这种情况下,您的if
检查将被绕过。
抛出 OutOfMemoryError通常会使虚拟机崩溃。(可以作为 Throwable 捕获)
您可能会发现从 Java OutOfMemory 错误中预防和恢复很有用。