Java - 本地类和泛型,为什么编译器警告?
问题描述:
命名为local classes很少使用,通常本地类是匿名的。有谁知道为什么下面的代码会生成编译器警告?Java - 本地类和泛型,为什么编译器警告?
public class Stuff<E> {
Iterator<E> foo() {
class InIterator implements Iterator<E> {
@Override public boolean hasNext() { return false; }
@Override public E next() { return null; }
@Override public void remove() { }
}
return new InIterator();
}
}
警告是new InIterator()
和它说
[unchecked] unchecked conversion
found : InIterator
required: java.util.Iterator<E>
如果类,不变的,是由匿名,或者如果它是由一个成员,警告消失。但是,作为已命名的本地班级,它需要声明class InIterator<E> implements ...
以使警告消失。
发生了什么事?
答
我现在确信这是一个javac错误。上面给InIterator添加一个通用参数的方法隐藏或替换E是没有用的,因为它们排除了迭代器做一些有用的事情,比如返回一个类型为E的东西的东西的E的元素。
然而,这编译与没有警告(感谢Jorn的提示):
public class Stuff<E> {
E bar;
Iterator<E> foo() {
class InIterator<Z> implements Iterator<E> {
@Override public boolean hasNext() { return false; }
@Override public E next() { return bar; }
@Override public void remove() { }
}
return new InIterator<Void>();
}
}
绝对是一个错误。
答
我相信发生了什么是你忽略了泛型类型参数,命名InIterator
而没有引用签名中的泛型(即使它存在于接口中)。
这属于愚蠢的编译器警告类别:您已编写该类,以便100%的实例将实现Iterator<E>
,但编译器无法识别它。 (我想这取决于编译器,我没有看到我的Eclipse编译器中的警告,但我知道Eclipse编译器处理的泛型与JDK编译器略有不同)。我认为这不太清楚,少接近你的意思,但也许更友好的编译器,并最终相当于:
public class Stuff<E> {
Iterator<E> foo() {
class InIterator<F> implements Iterator<F> {
@Override public boolean hasNext() { return false; }
@Override public E next() { return null; }
@Override public void remove() { }
}
return new InIterator<E>();
}
}
答
嗯,这里没有任何警告。
import java.util.Iterator;
public class Stuff<E> {
Iterator<E> foo() {
class InIterator implements Iterator<E> {
public boolean hasNext() {
return false;
}
public E next() {
return null;
}
public void remove() {
}
}
return new InIterator();
}
public static void main(String[] args) {
Iterator<String> i = new Stuff<String>().foo();
}
}
答
是的,我也同意这应该是一个错误。如果你将本地类从方法中“提升”到成员类中,它也可以正常工作。除了不同的范围和局部变量之外,两者之间没有太大的区别。
public class Stuff<E> {
class InIterator implements Iterator<E> {
@Override public boolean hasNext() { return false; }
@Override public E next() { return null; }
@Override public void remove() { }
}
Iterator<E> foo() {
return new InIterator();
}
}
只是出于好奇,我的编译器不会抱怨这个警告......您使用的是什么JVM? – 2009-04-21 14:57:06
Sun Java 6更新12 – Yardena 2009-04-21 15:54:49