Java解惑1-8 Dos Equis

2019 ワード

このパズルは、条件オペレータの習得度をテストします.このオペレータには、疑問符コロンオペレータというよりよく知られている名前があります.次のプログラムは何を印刷しますか?
public class DosEquis{
	public static void main(String[] args){
		char x = 'X';
		int i = 0;
		System.out.println(true ? x : 0); 
		System.out.println(false ? i : x); 
	}
}
このプログラムは、2つの変数宣言と2つのprint文で構成されています.最初のprint文は条件式(true?x:0)を計算し、charタイプ変数xの値'X'である結果を印刷します.2番目のprint文は式(false?i:x)を計算して結果を印刷するが、この結果は依然として「X」のxであるため、このプログラムはXXを印刷すべきである.しかし、プログラムを実行すると、X 88が印刷されていることがわかります.この行為は変に見える.最初のprint文はXで印刷され、2番目の印刷は88です.それらの異なる行為は何を説明していますか?
答えは条件式に関する部分を規範化する暗い隅にある.この2つの式では、各式の2番目と3番目のオペランドのタイプが異なります.xはcharタイプで、0とiはintタイプです.パズル5の解答で述べたように,混合型の計算は混乱を引き起こすが,これは条件式で他のどこよりも顕著に現れる.このプログラムの2つの条件式の結果タイプは同じであり、それらのオペランドタイプが同じであるように、オペランドの順序が逆になっているにもかかわらず、実際の状況はそうではないことを考えたことがあります.
条件式の結果タイプを決定するルールは冗長で複雑すぎて、完全に覚えにくいですが、その核心は次の3つです.
2、3の2点が本パズルに重要です.プログラムの2つの条件式では,1つのオペランドのタイプはcharであり,もう1つのタイプはintである.2つの式では、intオペランドはいずれも0であり、charとして表すことができる.しかしながら、第1の式のintオペランドのみが定数(0)であり、第2の式のintオペランドは変数(i)である.したがって、第2の点は第1の式に適用され、返されるタイプはcharであり、第3の点は第2の式に適用され、その返されるタイプはintとcharに対してバイナリ数値を用いて昇格したタイプ、すなわちintである.
条件式のタイプは、どのリロードprintメソッドが呼び出されるかを決定します.最初の式ではPrintStream.print(char)が呼び出され、2番目の式ではPrintStream.print(int)が呼び出されます.前のリロード方法では変数xの値をUnicode文字(X)として印刷し、後のリロード方法では10進数整数(88)として印刷した.これで謎が解けた.
要するに、通常は、条件式で同じタイプの第2および第3の操作数を使用することが望ましい.そうでなければ、あなたとあなたのプログラムの読者はこれらの表現の行為の複雑な規範を徹底的に理解しなければなりません.
言語設計者にとって、柔軟性の一部を犠牲にしたが、簡潔性を高める条件オペレータを設計することができるかもしれない.例えば、第2および第3の操作数には同じタイプが必要であり、これは合理的に見える.あるいは、条件オペレータは、定数に対して特別な処理がないと定義することができる.これらの選択がプログラマにとってより容易に受け入れられるように、すべての元のタイプの字面定数を表す文法を提供することができます.これは、言語の一貫性と完備性を増加させ、転換に対する需要を減少させるため、確かに良い注意かもしれません.
  • は、2番目と3番目のオペランドが同じタイプである場合、条件式のタイプである.言い換えれば、ハイブリッドタイプの計算を迂回することで、大きなトラブルを避けることができます. 
  • あるオペランドのタイプがTである場合、Tはbyte、shortまたはcharを表し、もう一つのオペランドはintタイプの定数式であり、その値はタイプTで表すことができ、条件式のタイプはTである. 
  • それ以外の場合、オペランドタイプにはバイナリ数値リフトが適用され、条件式のタイプは、2番目と3番目のオペランドがリフトされた後のタイプである.