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