我听说可以写一些像这样的代码
SomeClass obj = null;
try {
obj = new SomeClass();
} catch ( Exception e ) {
...
}
...
if ( obj != null ) { // here it holds true
...
}
有人可以解释一下,如果我们假设构造函数SomeClass 可能抛出一个异常,那么它是否可能以及在什么条件下?
另一个例子:
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
public class Sample{
static class A {
public static A s;
public A(Collection c) {
c.add(this);
s = this;
throw new RuntimeException();
}
}
@Test
public void testResource() throws Exception {
List l = new ArrayList();
A a = null;
try {
a = new A(l);
fail("Oops");
} catch (Throwable e) {
}
assertTrue(l.size() == 1);
assertNull(a);
assertNotNull(A.s);
assertNotNull(l.get(0));
}
}
答案 0 :(得分:2)
很有可能。
我不确定我理解你的问题,你自己已经回答了:如果构造函数抛出异常,obj可能为null。
答案 1 :(得分:2)
你当然可以编写这样的代码,它会编译并运行得很好。但永远不会出现obj
被“部分初始化”的情况。要么是,要么不会。具体来说,如果此行抛出Exception
:
obj = new SomeClass();
然后,就obj
的值而言,就好像该行从未被执行过一样。您在该行之前将obj
初始化为null
,因此如果抛出异常,则obj
仍为null
。在这种情况下,程序最后不会进入if
块。
或者,如果未抛出异常,则obj
将不再是null
,并且将执行最终if
块内的代码。
答案 2 :(得分:2)
首先声明并初始化变量。
SomeClass obj = null;
在以下行中,您(1)创建一个新实例,(2)存储引用。
try {
obj = new SomeClass();
} catch ( Exception e ) {
...
}
现在我们假设,实例化(步骤1)失败并抛出异常:JVM将在下一个处理该异常的catch块中继续。因此,步骤2将不会被执行,变量将保持其实际状态。
现在是可能部分初始化了一个实例。老实说,我不知道,那是JVM的内部。但由于没有任何内容可以参考这个部分初始化的实例,所以下次将会使用gc'd。
答案 3 :(得分:1)
这是完全可能的;仔细观察:如果构造函数抛出异常,obj
仍然是null
。
答案 4 :(得分:1)
如果SomeClass
构造函数抛出异常obj
将为NULL。
答案 5 :(得分:0)
对我来说,即使在调用构造函数之后,对象也为null:
public static void main(String[] args) {
TestCls cls = null;
try {
cls = new TestCls("");
} catch (Exception e) {
e.printStackTrace();
}
if(cls == null)
System.out.println("hi");
}
public TestCls(String str) throws Exception{
throw new Exception();
}
输出: -
java.lang.Exception
hi
at TestCls.<init>(TestCls.java:57)
at TestCls.main(TestCls.java:48)
结论:如果class constructor
引发Exception
,则obj
将NULL
。
答案 6 :(得分:0)
构造函数可以抛出异常,就像Java中的任何其他调用一样。例如,如果尝试在空引用上调用方法,它可能会抛出NullPointerException。请考虑以下示例:
public class ConstructionTest {
static ConstructionTest obj;
public ConstructionTest() {
String s = null;
s.hashCode();
}
public static void main(String[] args) {
try {
obj = new ConstructionTest();
} catch ( Exception e ) {
System.err.println(e);
}
if ( obj != null ) {
System.err.println("Not Null");
} else {
System.err.println("Is Null");
}
}
}
由于构造函数中的s为null,因此抛出NullPointerException,因此将打印“Is Null”。没有“部分构造的对象”的概念 - 当你在Java中使用new时,它既可以工作,又可以获得新实例化的对象,或者它不起作用,你就会得到异常。