1

次の (この形式では明らかに役に立たない) Java クラスがあります。

public class EntrySet<T> {

    public static class Entry<T> {
        T obj;
    }

    private final Set<Entry<T>> set;

    public EntrySet() {
        this.set = Sets.newHashSet();
    }

    public Set<Entry<T>> getEntries() {
        return set;
    }
}

このクラスを指定すると、以下はコンパイルされません。

EntrySet<?> entrySet = new EntrySet<SomeClass>();
Set<EntrySet.Entry<?>> entries = entrySet.getEntries();

2行目にコンパイルエラー「cannot convert from Set<EntrySet.Entry<capture#1-of ?>>to Set<EntrySet.Entry<?>>」があります。キャストまたはヘルパー関数を使用しても、このエラーを解消する方法が見つかりません。

ここでの問題は正確には何ですか?クリーンなコンパイルを取得する方法はありますか?

私ができる最善のことは次のとおりです。

EntrySet<?> entrySet = new EntrySet<SomeClass>();
Set<?> tmp = entrySet.getEntries();
Set<EntrySet.Entry<?>> entries = (Set<EntrySet.Entry<?>>) tmp;

これは明らかにひどいものです (関連する警告が抑制されていても)。

4

2 に答える 2

1

を削除entrySetしようとしていSet<EntrySet.Entry<SomeClass>>ますSet<EntrySet.Entry<?>>。本質的に同じことである何百ものスタックオーバーフローの質問があります。後者にaを追加することはできますがEntrySet.Entry<OtherClass>、前者に追加することはできません。そのため、型安全性が損なわれます。

おそらくこれに対処する方法は、(名前付きの)ジェネリックパラメーターを使用してメソッドを呼び出すことによってワイルドカードをキャプチャすることです。

    EntrySet<?> entrySet = new EntrySet<SomeClass>();
    fn(entrySet);
...
private static <T> void fn(EntrySet<T> entrySet) {
    Set<EntrySet.Entry<T>> entries = entrySet.getEntries();
于 2012-11-07T01:33:02.203 に答える
0

無制限のワイルド カード<?>は、すべてのジェネリック型のスーパー型のようなものです。これは、すべての Java クラスに対する Object クラスと似ています。無制限のワイルドカード参照に対して実行できる操作は、「null」を受け取る操作 (<?>引数参照でパラメーターが使用されている場合)、または「オブジェクト」を返す操作 (<?>戻り値の型参照でパラメーターが使用されている場合) のみです。したがって、Object 型の参照を返す場合、コードはコンパイルされます。

 class EntrySet<T> {

    public static class Entry<T> {
        T obj;
    }

    private final java.util.Set<Entry<T>> set;

    public EntrySet() {
        this.set = new java.util.HashSet();
    }

    public java.util.Set<Entry<T>> getEntries() {
        return set;
    }

    public static void main(String [] args){
        EntrySet<?> entrySet = new EntrySet<SomeClass>();

    //java.util.Set<EntrySet.Entry<?>> entries = entrySet.getEntries(); // Error

         Object o = entrySet.getEntries();         // OK !
    }
}

class SomeClass{}
于 2012-11-07T02:28:23.567 に答える