5

次のインライン条件では、整数と倍精度がそれぞれ出力されると予想される場合があります。

System.out.println(true ? 0 : 0.0);
System.out.println(false ? 0 : 0.0);
System.out.println(true ? new Integer(0) : new Double(0.0));
System.out.println(true ? 0 : "");

代わりに、一緒に発生した場合、両方とも double として出力されます。

 0.0
 0.0
 0.0
 0

インライン条件で他の数値が発生すると、数値が自動キャストされるのはなぜですか?

編集:オーバーロードされているためにこれが発生System.out.printlnしている場合、次の場合はどうなりますか:

list.add(true ? 0 : 0.0);
list.add(false ? 0 : 0.0);
list.add(true ? new Integer(0) : new Double(0.0));
list.add(true ? 0 : "");
System.out.println(list);

出力:

[0.0, 0.0, 0.0, 0]
4

4 に答える 4

16

インライン条件で他の数値と一緒に発生するときに、数値が自動キャストされるのはなぜですか?

条件式には単一の結果タイプが必要であり、そのタイプを使用して、のオーバーロードを使用するかどうかを決定System.out.printlnします。オーバーロードは常にコンパイル時に決定され、選択された条件に応じて、コンパイラが式に対して2つの完全に別個のパスを使用するのは非常に厄介です

条件に基づいて2つの異なることを行う場合は、を使用ますif。条件に基づいて、1つの結果タイプで2つの値から選択する場合は、条件演算子が最適です

編集:ここで興味深いケース、IMOは3番目のケースです。コンパイラーは、変換を実行せずに、を呼び出すことを選択できprintln(Object)ます。それが行われていないことを示すために、別のテストを行います。

Object x = true ? new Integer(0) : new Double(0.0);
System.out.println(x.getClass());

これは出力されclass java.lang.Doubleます-そしてバイトコードを見ると、intそれが箱から出されてから、として再箱に入れられていることがわかりDoubleます。すべてがどのように決定されるかについての厄介な詳細については、JLSのセクション15.25を参照してください。

于 2012-04-04T18:33:56.847 に答える
4

同じ三項演算に参加するには、条件演算子の両側に互換性がなければなりません。Java Language Specification 15.25によると、あなたの場合

バイナリ数値昇格 (§5.6.2) がオペランドの型に適用され、条件式の型は 2 番目と 3 番目のオペランドの昇格された型になります。

一般に、三項条件演算子の結果の型に到達するために言語が従う規則の長いリストがあります。詳細が必要な場合は、言語仕様をお読みください。

于 2012-04-04T18:37:18.600 に答える
0

EDITEDオーバーロードされている ためprintlnです。フォームの 1 つに解決する必要があり、両方をキャプチャする最小の型を選択します (最初の 2 つの例では int と double)。 void println(double x)

于 2012-04-04T18:34:01.567 に答える
0

共通タイプを採用。0 はロスレスで double に変換できます。(cond) の結果は? res1 : res2 は 1 つの戻り型でなければなりません。

于 2012-04-04T18:35:20.127 に答える