Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

GenericsにおけるCollection<T>

最近、Genericsを使っていて疑問に持った点が
ありましたので投稿します。
----------------------------------
import java.util.*;

public class test13{
    public static void main(String[] args){

        A<C> a = new A<C>();
        a.put(1, new C());
        a.put(2, new C());
        A a2 = a;

        B b = a2.get(1);          //*1
        for(B b2 : a2.values()){  //*2
            System.out.println(b2);
        }

    }
}
class A<T extends B>{
    private Hashtable<Integer,T> v = new Hashtable<Integer,T>();

    public void put(int i,T t){
        v.put(i,t);
    }
    public T get(int i){
        return v.get(i);
    }
    public Collection<T> values(){
        return v.values();
    }
}
class B{}
class C extends B{}
--------------------------------------
これだと、*1は通るのですが、*2でエラーになります。
つまり、Generics型の型指定を取り払った場合、
単純な型指定TはBとして扱われますが、Collection<T>は、Collection<B>ではなくCollection<Object>になってしまいます。
Collecton<B>になってくれると助かったのですが。

これは、やはりこのような仕様なのでしょうか?。

4

回答

2418

閲覧

4件の回答

評価

0

Genericsって実行時ではなく、あくまでコンパイル時のチェックだしねえ。
なくした時点で、内部はObjectもあり得るってことなのかも。

評価

0

いや、違うか。
コンパイル時にGenericsがない、つまりIterator itr = a2.values().iterator();になるから、
従ってObjectで受けなきゃいけないんだな。

評価

0

つまり、

Collection<C>c;
for (B b2 : c = a2.values()) {

一回変数に受けてやれば、警告は出るがエラーにはならない。

評価

0

そうか。
コンパイル時のチェックだから、
public T get() を実行時にBで受けることはできるけど、
public Collection<T> values()をCollection<B>で受ける事はできないんですね。
実行時には<>は消えちゃうわけですから。

なんとなく分かる気がします。
こりゃ、仕方ないですね・・・

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。