私が見ている振る舞いから始めるのがおそらく最善だと思います:
public class genericTest {
public static void main(String[] args) {
String str = "5318008";
printClass(str); // class java.lang.String
callPrintClass(str); // class java.lang.String
printClassVarargs(str); // class java.lang.String
callPrintClassVarargs(str); // class java.lang.Object
}
public static <T> void printClass(T str) {
System.out.println(str.getClass());
}
public static <T> void printClassVarargs(T ... str) {
System.out.println(str.getClass().getComponentType());
}
public static <T> void callPrintClass(T str) {
printClass(str);
}
@SuppressWarnings("unchecked")
public static <T> void callPrintClassVarargs(T str) {
printClassVarargs(str);
}
}
とを見るprintClass()
とcallPrintClass()
、すべてが正常に機能しているようです。callPrintClass()
一般的な引数を取り、それを渡します。printClass()
誰がパラメータを送信しているかを気にせずに、この変数を正しいタイプで認識し、想定どおりに実行して出力しjava.lang.String
ます。
しかし、varargsを使おうとすると、これは機能しなくなります。varargsのないメソッドが引数の型を認識するのと同じように、printClassVarargs()
引数が型であることを認識することを期待します。また、直接String[]
呼び出した場合(出力するのは完全に満足です)、これは発生しませんが、引数の型を忘れて、を取得していると推定する、によって呼び出された場合にのみ発生することにも注意してください。また、ここでコンパイラの警告を抑制しなければならないことも認識しています。これは通常、ジェネリックをキャストしようとしているときに発生しますが、そこで何が起こっているのか正確にはわかりません。printClassVarargs()
String
callPrintClassVarargs()
Object
だから私の質問は本当に2つです。この動作の背後にある理由は何ですか?これは型消去の結果ですか、それともJavaが配列を処理する方法ですか?そして第二に、これを回避する方法はありますか?
もちろん、これは単純な例にすぎません。私はこの方法でクラス名を出力しようとはしていませんが、配列を連結するためのオーバーロードされたメソッドを記述しているときに最初に問題を発見しました。