汎用コンパイラからもらった「蜜糖」のこと!


最近フォーラムでお兄さんたちを見て、反射の小さなテストプログラムのコードを書きました.
サンプルコード1は次のように動作します.
List<Integer> list1 = new ArrayList<Integer>();
list1.getClass().getMethod("add", Object.class).invoke(list1, "abc");
System.out.println(list1.get(0));

サンプルコード2の実行は次のように異常です.
ArrayList<String> list2 = new ArrayList<String>();
list2.getClass().getMethod("add", Object.class).invoke(list2, 12);
System.out.println(list2.get(0));

私が最初に考えたのは、Classオブジェクトを反射ロードして得られるaddの方法はタイプ消去されており、ArrayListのaddを1文字列にすることができるに違いない.もちろん反射もArrayListのaddを整数にすることができる.
しかし、上記の例のコード1は正常に動作していますが、コード2は異常に動作しています.なぜですか.最初はいつも汎用的なタイプの消去を考えていました.
あとはInteger Num=4;正常に実行してNumのオブジェクトを生成することができて、これは私が知っていて、コンパイラがあげた蜜糖で、
Integer inter=4はInteger inter=Integerに相当する.valueOf(4). つまりコンパイラが読み取る.JAvaファイルの場合、Integer inter=4になり、自動的に4をIntegerに置き換えます.valueOf(4).
int num=interの場合、コンパイラも全コードを補完してint num=interとなる.intValue(); これで運転時にも問題ありません.
では、この汎用引用の初心も煩わしい強転を取り除くのではないでしょうか.だから、コンパイラの仕業ではないでしょうか.対応する逆コンパイルツールを探しました.classファイルが逆コンパイルされ、次のことがわかりました.
コード2
System.out.println(list.get(0));

になる
System.out.println((String)list.get(0));

コード1では、コンパイラがコード1のArrayListがIntegerであることを見て、S.O.Pで呼び出すとObjectパラメータタイプのprintlnメソッドに転送できるので、そうする必要はありません.
これを理解して、それからまた相応の方法を探してテストします
次のようになります.
サンプル1のコードをサンプル3に変更しました.
List<Integer> list1 = new ArrayList<Integer>();
list1.getClass().getMethod("add", Object.class).invoke(list1, "abc");
System.out.println(list1.get(0).toString());

サンプルコード3でlist.get(0)の後にtoString()メソッドが呼び出されると,エラーが報告される.どうしてですか.
一言で言えば、コンパイラのやった鬼は自分で頭がいい.list.get(0)の前に強くなってIntegerに変わりました.
System.out.println(list1.get(0).toString())

コンパイラによって作られました.
System.out.println(
  ((Integer)list1.get(0)).toString()
);

終了:
汎用、自動梱包、引用自体も良いです.しかし、反射するときは、注意が必要です.コンパイラからもらった蜜糖は気をつけてください.
 
----編集後の補足:
ちょうどうっかりして可変パラメータを研究して、特徴は比較的に簡単で、例えば1.可変パラメータタイプの後に続く3つの小さな点が必要です.  .3つの小さな点は、変数名のパラメータの後ろに置くことはできません.変数名とタイプの間に置くことしかできません.真ん中にスペースがあるかどうかは重要ではありません.
しかし、タイプの後ろに3つの小さな点が続くことをお勧めします.
2.消費メソッドを呼び出す場合も比較的簡単で、複数の実パラメータをサポートすることができ、可変の実パラメータ伝達(いわゆる実パラメータ数可変)
 
原理は、なぜ可変パラメータをサポートできるのか、Type...道は何なのか、伝わる実パラメータはなぜ可変なのか.
長いこと説明していないので、後でコンパイラのメリットかどうか考えてみましょう.そこで、次のテストがありました.
avilabePareDemo("asdfa","badf","323"); // main , , main 。

public static void avilabePareDemo(String... args){
		for(int i=0;i<args.length;i++){
			System.out.println(args[i]);
		}
	}

逆コンパイルを経て、意外にもコンパイルされました.
avilabePareDemo(new String[] { "asdfa", "badf", "323" });

public static void avilabePareDemo(String[] paramArrayOfString) {
    for (int i = 0; i < paramArrayOfString.length; ++i)
      System.out.println(paramArrayOfString[i]);
  }

上から見ると:
1.呼び出し先のコンパイラは、new String[]{"asdfa","badf","323"}の配列を自動的に追加し、前の"asdfa","badf","323"の3つのパラメータを置換します.
2.可変メソッドのパラメータは、String[]paramArrayOfStringに逆コンパイルされ、前の可変Stringに置き換えられました...