List<Collection> a = new ArrayList<Collection>();
Set<String> s = new HashSet<String>();
Set<Integer> c = new HashSet<Integer>();
s.add("hello");
s.add("world");
//
c.add(200);
c.add(300);
//
a.add(s);
a.add(c); List<Double> d = new Linked<Double>();
d.add(200.98);
d.add(33.090);
a.add(d);
for (Iterator<Collection> i = a.iterator(); i.hasNext();) {
//问题:
Iterator w = i.next().iterator();
while(w.hasNext()) {
out.println(w.next());
}
}Iterator w = i.next.iterator(); Iterator为什么不用声明类型?
如果不声明是不是返回Iterator<Object>;的类型呢?
Set<String> s = new HashSet<String>();
Set<Integer> c = new HashSet<Integer>();
s.add("hello");
s.add("world");
//
c.add(200);
c.add(300);
//
a.add(s);
a.add(c); List<Double> d = new Linked<Double>();
d.add(200.98);
d.add(33.090);
a.add(d);
for (Iterator<Collection> i = a.iterator(); i.hasNext();) {
//问题:
Iterator w = i.next().iterator();
while(w.hasNext()) {
out.println(w.next());
}
}Iterator w = i.next.iterator(); Iterator为什么不用声明类型?
如果不声明是不是返回Iterator<Object>;的类型呢?
这是你没有声明,最好还是声明。如果不声明是不是返回Iterator<Object>;的类型呢?
不是,泛型的不限制通配符是Iterator<?>
确实是声明了反而报警告,但是这个警告不是因为你声明了Iterator的<Collection>而报的,而是因为Collection本身也需要声明Collection<?>
泛型的限定;
? extends E: 可以接收E类型或者E的子类型。上限。
? super E: 可以接收E类型或者E的父类型。下限
Iterator w = i.next().iterator();我认为这里Iterator已没必要声明类型,包括占位符.因为在 List<Collection> a = new ArrayList<Collection>()就已经填充了占位符!例如我们定义一个接口使用泛型声明
public inteface Welcome<E>{
void add(E x);
Iterator<E> iterator();
}
E会被填充
就像楼主举的例子,如果i.next().iterator()返回的是Iterator<List>,而你声明引用只是用原生态的类型Iterator,那么再使用的时候,你要调用List的方法,还要重新显式类型转换。而且在别的地方,或者别人用你的Iterator的时候如果不注意,也很容易出错。
------------------------------------------------
同时,我也要纠正一下上面几楼的说法:
我用List这个熟悉的类型来说吧,
List是原生态的List类型;List<Object>是任意类型的参数化List类型;List<?>是无限通配符的List类型。
这三者是不同的,第一个逃避了泛型检查,而第二个明确告诉编译器能够持有任意Object的对象,如List<String>可以赋给List,却不能赋给List<Object>。
而第三个定义起来和第一个很像,定义的时候也不会进行类型检查,但是如果写入的话就会有问题,例如List<?> l = new ArrayList<String>();
l.add(""); // 这样会报错,因为String和?冲突了
具体可以参考《Effective Java》第二版,23条,请不要在新代码中使用原生态类型