0

ideone.com に見られるように、次のコードがあります。

import java.util.*;

class Test{
   interface Visitor{
        public <T> void visit(T Value);
   }

   class MyVisitor<T> implements Visitor{
        List<T> list = new  ArrayList<T>();

        public <T> void visit(T value){
           list.add(value);
        }
    }
}

このコードをコンパイルすると、次のエラーが発生します。

Main.java:12: エラー: add(T#1) に適したメソッドが見つかりません
             list.add(値);
                 ^
     メソッド List.add(int,T#2) は適用されません
       (実引数リストと仮引数リストの長さは異なります)
     メソッド List.add(T#2) は適用されません
       (実際の引数 T#1 は、メソッド呼び出し変換によって T#2 に変換することはできません) ここで、T#1、T#2 は型変数です。
     T#1 はメソッド visit(T#1) で宣言されたオブジェクトを拡張します
     T#2 extends Object 宣言されたクラス Test.MyVisitor 1 エラー

問題は、 visit の型 Tが listの同じ T と見なされないことです。このコンパイルの問題を修正するにはどうすればよいですか?

4

5 に答える 5

1

インターフェイスはVisitor<T>

編集:インターフェースは次のようにする必要があります

interface Visitor<T> {
    void visit(T Value);
}
于 2013-04-11T11:27:04.030 に答える
0

正しい解決策は次のとおりです。

class Test {
    interface Visitor<T> {
        public void visit(T Value);
    }

    class MyVisitor<T> implements Visitor<T> {
        List<T> list = new ArrayList<T>();

        @Override
        public void visit(T value) {
           list.add(value);
        }
    }
}
于 2013-04-11T11:33:24.613 に答える
0

の型パラメーター(したがって、の項目の型) を、メソッド シグネチャの型パラメーターTでシャドウイングしています。これは、まったく異なる型になる可能性があります。( which に渡される任意の型は、任意の型である可能性があり、.) どちらか一方の名前を変更する必要があります。MyVisitor<T>listvisit()Object

実際、ビジターのメソッド シグネチャは、Java ジェネリックに関する限り、意味がありません。それを作るだけでvoid visit(Object o)、まったく同等で混乱が少なくなります。そうすることで、問題がより明確になります。 に を追加しようとしてObjectList<T>ます。メソッドのシグネチャが必要な場合はVisitor、キャストする必要があります。(これには a が必要になるため、Class.cast()a のClass<T>どこかにMyVisitor)

于 2013-04-11T11:35:59.857 に答える