9

これは、Joshua Bloch による Google I/O パズル トークから入手しました。これがコードです

 public class Glommer<T> {
      String glom(Collection<?> obj){
         String result = "";
         for(Object o : obj){
              result += o;
         }
         return result;
      }

      int glom(List<Integer> ints){
           int result = 0;
           for(int i : ints){
                result += i;
           }
           return result;
       }

      public static void main(String args[]){
           List<String> strings = Arrays.asList("1", "2", "3");
           System.out.println(new Glommer().glom(strings));
      }

このメイン メソッドは例外をスローします。これnew Glommerは が生の型であるためであり、そのため のすべてのジェネリックGlommerが消去されるため、最終int glom(List<Integer> ints)的にString glom(Collection<?> obj).

私の質問は、型消去のためにメソッドを呼び出すべきではないglom()として呼び出したとしても、このメソッドは効果的であり、型ではないのでしょうか?new Glommer<Integer>().glom(strings)int glom(List<Integer> ints)int glom(List ints)stringsListCollection

4

3 に答える 3

7

呼び出されたメソッドは、実行時ではなくコンパイル時に定義されます。

コンストラクター呼び出しにパラメーターを追加すると、コンパイラーは、最初のメソッドを呼び出す必要があることを知るのに十分な情報を取得します。そうでなければ、ジェネリックが存在しなかったのと同じです。どちらの場合も、呼び出されたメソッドは実行時に常に同じままです。

編集 一部の人々は疑っているようなので、別の例を次に示します。

public class Test {

    private static void test(Object object) {
        System.out.println("Object method");
    }

    private static void test(Integer integer) {
        System.out.println("Integer method");
    }

    public static void main(String[] args) {
        Object object = Integer.valueOf(0);
        test(object);
    }

}

結果は次のとおりです。

Object method

メソッドに Integer を渡しますが、コンパイラがコンパイル時に知っているのは、それがオブジェクトであることだけです。オブジェクトが実際には整数であっても、jvm はメソッド呼び出しを自動的に変更しません。

于 2012-12-20T17:14:07.320 に答える
1

完全に理解するには、 Raw タイプの詳細を読むことができます。

基本的に、生の型はレガシー コードを使用するためのものであり、生のクラスのほとんどすべてが生そのものになります。この場合、これら 2 つのメソッドです。

したがって、それが生の場合、1つを取得するメソッドがありList、1つCollectionと呼ばれ、List生でない場合、メソッドも生ではなくCollection、追加情報があるため、1つを呼び出します

于 2012-12-20T17:36:44.517 に答える
0

これは、new Glommer()がジェネリックなしで呼び出されるとGeneric<Type>()、すべての型の一致がクラスから削除されるためです。

文字列変数は であるためList、ジェネリックがない場合<Type>glom(List ints). 型チェックは後で行われます。

型を作成するnew Glommer<AnyType>と、すべての型がそのまま残るので、strings変数を渡すと型チェックが行われます。コンパイラは、それが であるかどうかを確認できるようになりましたがList<Integer>、そうではないため、メソッドに渡されglom(Collection<?> obj)ます。

これがお役に立てば幸いです。必要に応じて説明を求めてください。

于 2012-12-20T17:08:20.897 に答える