77

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

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

第二行在 Eclipse 中被标记为死代码,我明白为什么。似乎没有显式抛出异常,构造函数也不可能MyObject抛出任何类型的异常(例如NullPointerExceptions)。

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

4

11 回答 11

99

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

于 2012-06-19T14:46:25.680 回答
54

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

MyObject o = createMyObject("parameter");
if (o == null) o = createMyObject("fallback parameter");
于 2012-06-19T14:47:27.897 回答
52

JLS 的第 15.9.4 节

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

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

于 2012-06-19T14:50:38.660 回答
24

我的猜测是它是由一个 C 程序员编写的,他习惯于测试malloc()for的返回值,如果您的系统内存不足NULLmalloc()可以返回。NULL

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

于 2012-06-19T18:17:13.147 回答
8

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

于 2012-06-19T15:22:31.637 回答
4

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

于 2012-06-19T14:46:37.847 回答
4

当您创建一个new Object()时,您会在内存中创建一个地址,并且该地址不是“null”,但您的 Object 可能为空。

您必须为参数传输的对象测试“空”。

于 2012-06-19T14:46:50.173 回答
4

这只是死代码。

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

于 2012-06-19T14:47:43.573 回答
4

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

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

在这种情况下,Foo 的构造函数中的代码被完全绕过new Foo(...)。但是,如果您编写了一个测试,但没有以上述方式指定模拟,那么您最终可能会得到null相反的结果。

但是即使您使用这样的框架,您也不希望在您的类中添加额外的代码,只是为了优雅地处理您忘记在测试中正确模拟对象的情况!这不是您的代码打算运行的真实场景。无论如何都应该消除只有在测试时才处于活动状态的代码,在这种情况下,它只会在测试失败时才处于活动状态。

因此,即使您使用的是 PowerMock,第二行也应该被正确地视为“死代码”并删除。

于 2015-10-21T00:26:58.657 回答
0

这个问题是绝对合法的。您可以像这样添加静态方法MyObject

static MyObject create(String parameter)) {
       if (parameter.satisfySomething())
          return new MyObject(parameter);
       else
          return null;
}
于 2021-01-02T09:41:39.487 回答
0

所有答案都基于理论和编辑的警告。

事实上,大多数编辑器在针对 null 测试 new object() 的结果时会报告死代码。

但是,至少在 Android 上,我有很多关于新 xxx() 返回 null 的崩溃报告,我认为在大多数情况下是因为内存不足。

一个简单的例子是这样的:

object_class obj = new object_class(context);
obj.getCount();

我在 getCount() 行得到这样的报告:

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“int object_class.getCount()”

所以这是可能的,但大多数编辑器/编译器不会让你检查这种情况。

于 2021-09-04T20:00:18.767 回答