构造函数可以返回一个null对象吗?

时间:2012-06-19 14:44:16

标签: java constructor null

在查看一些旧代码时,我遇到了这个宝石:

MyObject o = new MyObject("parameter");
if (o == null) o = new MyObject("fallback parameter");

第二行在Eclipse中标记为死代码,我理解为什么。似乎没有明确抛出任何异常,MyObject构造函数不可能抛出任何类型的异常(例如NullPointerException s)。

我的问题是为什么有空检查?以前是否可以在旧版本的Java中使构造函数返回null?或者这只是无用的死代码?

10 个答案:

答案 0 :(得分:87)

代码在任何Java版本中都是死的。构造函数不可能返回null,即使从构造函数抛出异常,也不会调用下一行。

答案 1 :(得分:51)

不,这是不可能的。也许以前版本的代码使用了一些可以返回null的工厂方法:

MyObject o = createMyObject("parameter");
if (o == null) o = createMyObject("fallback parameter");

答案 2 :(得分:49)

来自section 15.9.4 of the JLS

  

类实例创建表达式的值是对指定类的新创建对象的引用。每次计算表达式时,都会创建一个新对象。

所以不,它永远不会返回null。

答案 3 :(得分:23)

我的猜测是,它是由C程序员编写的,用于测试malloc()的{​​{1}}的返回值,NULL如果您的系统可以返回malloc()内存耗尽。

代码在Java中没有意义,因为如果内存不足,Java将抛出OutOfMemoryError`。

答案 4 :(得分:8)

答案很简单:编写代码的人是一个偏执的c ++程序员。在C ++中,您可以重载operator new并将其用作简单的内存分配器(也称为malloc)。

答案 5 :(得分:4)

这只是无用的死代码。一旦CTOR成功执行,您就可以引用该对象。

答案 6 :(得分:4)

当你创建一个 new Object()时,你在内存中创建一个地址,这个地址不是'null',但是你的Object可能是空的。

您必须为参数传输的Object测试'null'。

答案 7 :(得分:3)

这只是死代码。

new MyObject("parameter")不会在任何版本的java中返回null

答案 8 :(得分:2)

正如我今天发现的那样,尽管在所有其他答案中都有所说,Foo x = new Foo(...)确实可以返回null,如果所述代码在使用PowerMock的测试中运行(或其他一些)具有类似效果的模拟框架):

PowerMockito.whenNew(Foo.class).withAnyArguments().thenReturn(mockFoo);

在这种情况下,new Foo(...)完全绕过Foo构造函数中的代码。但是,如果您编写的测试未能按上述方式指定模拟,则最终可能会使用null

即使你正在使用这样的框架,你也不需要在你的类中添加额外的代码,只是为了优雅地处理你忘记在测试中正确模拟对象的情况! 是您的代码要运行的真实场景。无论如何,应该在测试时仅消除活动的代码,并且在这种情况下,它只会在破坏的测试中处于活动状态。

所以,即使您正在使用PowerMock,也应该正确地考虑第二行"死代码"并删除。

答案 9 :(得分:0)

这个问题绝对合理。您可以像这样在 MyObject 中添加静态方法:

static MyObject create(String parameter)) {
       if (parameter.satisfySomething())
          return new MyObject(parameter);
       else
          return null;
}