web-dev-qa-db-ja.com

コンストラクターはnullオブジェクトを返すことができますか?

古いコードを調べていると、この宝石に出会いました。

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

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

私の質問はなぜ nullチェックがありますか?以前のJavaの古いバージョンでは、コンストラクターがnullを返すことは可能でしたか?または、これは単に役に立たないデッドコードですか?

74
Jonathan Pitre

Javaのどのバージョンでもコードは死んでいます。コンストラクターがnullを返すことはできません。また、コンストラクターから例外がスローされる場合でも、次の行は呼び出されません。

89
tibtof

いいえ、不可能です。以前のバージョンのコードでは、nullを返す可能性のあるファクトリメソッドが使用されていた可能性があります。

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

JLSのセクション15.9.4 から:

クラスインスタンス作成式の値は、指定されたクラスの新しく作成されたオブジェクトへの参照です。式が評価されるたびに、新しいオブジェクトが作成されます。

いいえ、nullを返すことはできません。

49
Jon Skeet

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

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

23
Jack Edmonds

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

8
kofemann

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

4
Yair Zaslavsky

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

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

4
cl-r

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

new MyObject("parameter")は、Javaのどのバージョンでもnullを返しません。

3
Alex Lockwood

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

_PowerMockito.whenNew(Foo.class).withAnyArguments().thenReturn(mockFoo);
_

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

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

そのため、PowerMockを使用している場合でも、その2行目は「デッドコード」と見なされて削除されるはずです。

3
Zac Thompson