我写了一些使用泛型的代码,但遇到了以下情况,我无法理解:
我有一个接口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类型的对象,但如果我使用原始类型并执行以下操作:
Scope myScope = new Scope();
scope.getRangesList().get(0)
我得到了Object对象,除非我明确将其转换为Range,否则我无法使用ipRange方法。
如果是List<T>
,我就理解了,因为我使用了原始类型,编译器无法知道列表项的实际类型,但在这种情况下,它将始终是IpRange类型,那么为什么我没有得到Object?
问题在于,当我创建范围时,我不一定知道实际的范围类型。考虑这个构造函数:public Scope(String rangeStringList); 就我所知,字符串可以是"16.59.60.80"或"fe80::10d9:159:f:fffa%"。但我知道的是,我向编译器传递了一些IpRange对象,并且我希望能够使用此接口,无论这是ipv4还是ipv6。由于编译器可以确定这是ipRange,即使我使用了原始类型,我想知道为什么Java选择以这种方式进行。
Scope<? extends IpRange<?>> myScope = new Scope<Ipv4>();
这样。 (绝对没有理由实例化原始类型。) - millimooseIpRange
对象,它是Ipv4Range
或Ipv6Range
。编辑:实际上,您可能根本不需要泛型。泛型(在Java中)的目的是在您获取结果时消除强制转换,而由于您没有使用它进行强制转换,因此所有这些都有点无意义... - Jeffpublic class Scope {
和public List<IpRange<IP>> getRangesList() {return rangesList;}
因为你在编译时不使用T
的值。编辑:显然还要从字段中适当地移除泛型... - Jeff