77

いくつかの古いコードを調べているときに、この宝石に出くわしました:

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

2 行目は Eclipse でデッド コードとしてマークされていますが、その理由は理解できます。例外は明示的にスローされないようであり、MyObjectコンストラクターがあらゆる種類の例外 ( NullPointerExceptions など) をスローすることはできません。

私の質問は、なぜnull チェックがあるのですか? 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

私の推測では、malloc()forNULLの 戻り値をテストすることに慣れている C プログラマーによって書かれたもので、システムのメモリが不足した場合にmalloc()戻ることができます。NULL

Java はメモリ不足になると OutOfMemoryError` をスローするため、このコードは Java では意味がありません。

于 2012-06-19T18:17:13.147 に答える
8

答えは簡単です。コードを書いた人は偏執狂的な C++ プログラマーでした。C++ では、演算子 new をオーバーロードして、単純なメモリ アロケータ (別名 malloc) として使用できます。

于 2012-06-19T15:22:31.637 に答える
4

これは単に役に立たないデッド コードでした。CTOR が正常に実行されると、オブジェクトへの参照が得られます。

于 2012-06-19T14:46:37.847 に答える
4

new Object()を作成すると、メモリ内にアドレスが作成されます。このアドレスは「null」ではありませんが、オブジェクトは空である可能性があります。

パラメータによって送信されるオブジェクトの「null」をテストする必要があります。

于 2012-06-19T14:46:50.173 に答える
4

それは単なるデッドコードです。

new MyObject("parameter")nullJava のどのバージョンでも返されません。

于 2012-06-19T14:47:43.573 に答える
4

今日私が発見したように、他のすべての回答で述べられていることにもかかわらず、PowerMock (または同様の効果を持つ他のモック フレームワーク)Foo x = new Foo(...)を使用するテスト内で上記のコードが実行されている場合、実際には null を返す可能性があります。

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

この場合、 Foo のコンストラクター内のコードは、 に対して完全にバイパスされnew Foo(...)ます。しかし、上記の方法でモックを指定しないテストを作成すると、null代わりにモックが作成される可能性があります。

ただし、そのようなフレームワークを使用している場合でも、テストでオブジェクトを適切にモックするのを忘れた場合を適切に処理するために、クラスに余分なコードは必要ありません! これは、コードの実行が意図されている実際のシナリオではありません。とにかくテストを排除する必要がある場合にのみアクティブになるコード。この場合、テストが壊れた場合にのみアクティブになります。

したがって、PowerMock を使用している場合でも、その 2 行目は「デッド コード」と見なして削除する必要があります。

于 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 に答える