7

参照: http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html

「あなたのプログラムが null を autounbox しようとすると、NullPointerException がスローされます。」

ブール値に null を代入しようとすると、javac はコンパイル時エラーを出します。理にかなっています。ただし、ブール値に null を割り当てることは問題ありません。も意味があると思います。

しかし、null を autounbox しようとすると NPE が発生するという事実について考えてみましょう。これが意味することは、null チェックまたは例外処理なしでは、ブール値に対してブール演算を安全に実行できないということです。整数に対して数学演算を行う場合も同様です。

長い間、私は Java1.5+ のオートボクシングのファンでした。なぜなら、Java が真のオブジェクト指向に近づいたと思ったからです。しかし、昨夜この問題に遭遇した後、私はこれがひどいと思うと言わざるを得ません. 初期化されていないプリミティブを使用しようとすると、コンパイラがエラーを出すのは良いことです。それを失った場合、オートボクシングを使用したくありません。

オートボクシングのポイントを誤解している可能性があると思いますが、同時に、ブール値が 3 つの値を持つことができるべきであることを決して受け入れません。誰でもこれを説明できますか?私は何を得ていないのですか?

4

9 に答える 9

16

ボックス型は参照型であり、プリミティブボックスであるかどうかに関係なく、すべての参照型はを参照できますnull。そのため、Booleanはを参照できますnull。だからできますInteger。だからString、などができます。

ボックス型は、Javaを真にオブジェクト指向にするようには設計されていません。Javaが純粋なオブジェクト指向言語になることは決してないので、そうであるかのようにコーディングしないでください。プリミティブ型がなくなることはありません。実際、選択肢がある場合は常に優先する必要があります。

これは、Effective Java 2nd Edition、Item 49からの引用です:ボックス化されたプリミティブよりもプリミティブ型を優先します(作成者による強調):

要約すると、選択できる場合は常に、ボックス化されたプリミティブよりもプリミティブを使用します。プリミティブ型はより単純で高速です。ボックス化されたプリミティブを使用する必要がある場合は、注意してください。自動ボクシングは、ボックス化されたプリミティブを使用する際の冗長性を軽減しますが、危険性は軽減しません。プログラムが2つのボックス化されたプリミティブを==演算子と比較するとき、それはID比較を行いますが、これはほぼ確実にあなたが望むものではありません。プログラムがボックス化されたプリミティブとボックス化されていないプリミティブを含む混合型の計算を行う場合、プログラムはボックス化解除を行い、プログラムがボックス化解除を行う場合、をスローする可能性がありNullPointerExceptionます。最後に、プログラムがプリミティブ値をボックス化すると、コストがかかり、不要なオブジェクトが作成される可能性があります。

于 2010-05-27T17:21:04.547 に答える
7

nullこの値が役立つケースを少なくとも 1 つ見てきました。Web サービスの多くのデータ オブジェクトには、null 可能なブール フィールドがあります。ユーザーが値を含めることを怠る場合があります。この場合、値がデフォルト値から欠落していることを識別できるようにする必要があります。getX以前は、 、setX、およびisXSet()メソッドを記述していました。 whereisXSetは、誰かが を呼び出すまで false を返しますsetX。をnull許容型にするXことが可能になり、 return の場合に設定されていないことは明らかです。getXnull

于 2010-05-27T17:28:30.473 に答える
5

ここで述べたことすべてに加えて、ブール値の 3 番目の値が非常に必要な場合があります。これは「オプションの」プロパティの場合です。

通常、null を許可するブール列を持つデータベースで発生します。ブール値を使用しないと、2 つの個別の変数を使用する必要があります。1 つは値を示し、もう 1 つは値が有効かどうかを示します。

実際、JDBC API を見ると、この問題の例を見ることができます。列が null の場合 (たとえば、数値フィールドの場合は 0)、列がデフォルト値を取得し、「wasNull」を呼び出す必要があります。真の 0 か偽の null かをチェックしてください!

于 2010-05-27T17:24:45.490 に答える
4

あなたの問題は、オートボクシングではなく、オートアンボクシングにあります。私は、より重大な理由から、自動ボックス化解除は悪だと思います:

このことを考慮:

Integer i = new Integer(1);
Integer i2 = new Integer(12);

System.out.println(i == 10 || i != i2);

1つ==は開梱し、もう1つは開梱しません。

演算子のボックス化解除 (割り当てとは対照的に) は、私の見解では間違いでした (上記を考えると、それは Java ではありません)。しかし、ボクシングはとてもいいです。

于 2010-05-27T17:31:52.850 に答える
1

技術的な質問よりも哲学的な質問だと思います。プリミティブ型を参照型に変換するときは、参照型(つまりオブジェクト)がnull許容であることを確認する必要があります。

CAR Hoareがoop(Algol 60)へのnull参照を導入したのは間違いだったと言っている、The BillionDollarsMistakeのプレゼンテーションを見ることができます。

効果的なJavaのJoshBlochは、可能な場合はプリミティブ型を優先することを推奨しています。ただし、ブール変数をnullに対して検証する必要がある場合があります。

于 2010-05-27T17:21:23.147 に答える
0

オートボクシングは、データ型を組み込み型とオブジェクト型の間で自動的に変換します。

ブール値のオブジェクトタイプは、、、Boolean.TRUEまたはBoolean.FALSEですnull。そのため、ブール値の可能な3つの値を処理する必要があります。

データベースでは、ブール型に対して3つの状態を持つのが一般的です。誰かがクラスに合格したかどうかを追跡するレコードを考えてみましょう。合格するためのTRUEがあります。合格しない場合はFALSE、「現在クラスを受講している」場合はNULL。はい、それは奇妙ですが、値を持たないことはオブジェクト指向プログラミングで継承されます。

私もオートボクシングは少し不快だと思います。これは主に、コンパイラが変換プロセスを処理するためにバイトコードを追加する機能だからです。私の意見では、これは人々が変換プロセスの重要な詳細を忘れてしまう可能性があり、それはよりよく覚えられているかもしれません(あなたの場合のnull処理など)。これは便利ですが、Java言語の他のほとんどの機能ほど便利ではありません。

個人的には、組み込み型が「組み込み」タイプではなく軽量オブジェクトとして実装されることを望みます。ハイブリッド組み込み/オブジェクト型システムが邪魔になることがよくあります。とはいえ、組み込み関数はパフォーマンスを向上させるために存在するはずでしたが、オブジェクトマーシャリングに多くの組み込み関数を実行する必要がある場合、組み込み関数のみのパフォーマンスの向上を楽しむことはできないようです。

于 2010-05-27T17:20:27.580 に答える
0

のように、オートボクシングの問題Integer i = null;です。Integerオブジェクトは null にすることができますが、ネイティブは null にするintことはできません。

于 2010-05-27T17:31:33.433 に答える
0

実際、Java 1.5 より前の時代と大きな違いはありません。問題はブール型 (まだ 2 つの状態があります) ではなく、ブール型ラッパー (常に 3 つの状態、Boolean.TRUE、Boolean.FALSE、null) にあります。

Boolean オブジェクトから Boolean プリミティブへのすべての変換には、オートボクシングの有無にかかわらず、null チェックが必要です。

于 2010-05-27T17:22:00.413 に答える
0

オートボクシングの導入により、プリミティブを置き換えることは意図されていませんでした。ほとんどの場所では、プリミティブが必要です。「Javaが真のオブジェクト指向に近づいた」という理由で参照型の使用を開始したい場合は、それがあなたの呼びかけですが、発見しているように、そのアプローチには欠点があります。パフォーマンスは別の問題になります。

オートボクシング (およびオートアンボクシング) は、プリミティブを使用するコード (大部分) と参照型を使用する必要があるコード (まれ) の間の移行を支援するためにあります。参照型の中で、Boolean は間違いなく最も希少です。これは、インスタンス数が少ないため、コレクションに入れる価値がほとんどないことを意味します。

要約すると、参照型が問題を引き起こしている場合は、それらを使用しないでください。しかし、自分の状況では役に立たなかったからといって、「オートボクシングは悪い」とは言わないでください。

于 2010-05-27T17:34:36.107 に答える