繁体   English   中英

Java-本地类和泛型,为什么会出现编译器警告?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM