[英]Why does the java compiler give “rawtypes” warning for class literal?
[英]Java - local class and generics, why compiler warning?
命名本地类很少使用,通常本地类是匿名的。 有人知道为什么下面的代码会生成编译器警告吗?
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 ...
才能消除警告。
这是怎么回事?
我相信发生的事情是您通过命名InIterator
忽略了泛型类型参数而没有在签名中引用泛型(即使它存在于接口中)。
这属于愚蠢的编译器警告类别:您已编写该类,以便100% InIterator
实例将实现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();
}
}
我现在确信这是一个javac错误。 上面为InIterator添加通用参数以隐藏或替换E的解决方案没有帮助,因为它们使迭代器无法做一些有用的事情,例如返回E类型的东西-Stuff'sE。
但是,编译时不会发出警告(感谢乔恩的提示):
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>();
}
}
绝对是一个错误。
是的,我也同意这应该是一个错误。 如果将本地类从方法中“提升”到成员类中,它也可以正常工作。 两者之间没有太大区别,只是作用域和访问局部变量的方式不同。
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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.