ジェネリックスを使用していくつかのコードを記述しましたが、理解できなかった次の状況に陥りました。
インターフェイスIpRangeと次のクラスがあります。
public class Scope<IpRange<T extends IP>> {
List<IpRange<T>> rangesList;
public List<IpRange<T>> getRangesList() {return rangesList;}
}
今、私が次のように書いた場合、いくつかのテストクラスから:
Scope<Ipv4> myScope = new Scope<Ipv4>();
scope.getRangesList().get(0)
IpRange型のオブジェクトを取得していますが、raw型を使用してこれを実行している場合:
Scope myScope = new Scope();
scope.getRangesList().get(0)
Objectを取得していますが、明示的にRangeにキャストしない限り、ipRangeメソッドを使用できません。
生のタイプを使用したので、コンパイラはリストアイテムの実際のタイプを知る方法がありませんが、この場合List<T>
は常にIpRangeタイプになるので、なぜObjectを取得しないのですか? ?
問題は、スコープを作成するときに、実際の範囲タイプが必ずしもわからないということです。このコンストラクターについて考えてみます。publicScope(String rangeStringList); 私が知っている限りでは、文字列は「16.59.60.80」または「fe80 :: 10d9:159:f:fffa%」である可能性があります。しかし、私が知っているのは、IpRangeオブジェクトをコンパイラーに渡したということです。これがipv4でもipv6でも、このインターフェイスを使用できると期待しています。また、行タイプを使用した場合でも、コンパイラはこれがipRangeであることを確実に認識できるため、Javaがこの方法を選択したのはなぜかと思います。