当我编译以下 Java 代码时(使用 Oracle JDK 1.7.0_25):

public class StackOverflowQuestion {

    interface Example {

        <T extends Example> T init();
    }

    static class ExampleImpl implements Example {

        @Override
        public ExampleImpl init() {
            return this;
        }
    }
}

我收到警告:
StackOverflowQuestion.java:11: warning: [unchecked] init()
  in ExampleImpl implements <T>init() in Example
        public ExampleImpl init() {
                           ^
  return type requires unchecked conversion from ExampleImpl to T
  where T is a type-variable:
    T extends Example declared in method <T>init()

我不明白为什么它说“返回类型需要未经检查的转换”,因为该类实现了 Example 就我所见,它是一个有效的返回类型。

任何人都可以向我解释什么是错的?

最佳答案

Example 中的泛型方法应该可以在 T 可以是扩展 Example 的任何类型的情况下工作,但是您已经尝试在 ExampleImpl 中以这样一种方式实现它,它总是返回一个 ExampleImpl 。如果 ExampleImpl 是唯一实现 Example 的类,这可能没问题,但如果还有其他类,您可以在运行时获得 ClassCastException

在下面的示例中,我们实例化一个新的 ExampleImpl ,将其转换为基本接口(interface),然后使用 init() 等于 T 调用泛型方法 ExampleImpl2 。这应该返回一个 ExampleImpl2 ,但是由于您返回了 this ,它会抛出一个 ClassCastException 。这就是您的代码必须生成警告的原因。

public class StackOverflowQuestion {

    interface Example {

        <T extends Example> T init();
    }

    static class ExampleImpl implements Example {

        @Override
        public ExampleImpl init() {
            return this;
        }
    }

    static class ExampleImpl2 implements Example {

        @Override
        public <T extends Example> T init() {
            return null;
        }
    }

    public static void main(String[] args) {
        ExampleImpl2 e2 = ((Example) new ExampleImpl()).<ExampleImpl2>init();
    }
}

关于java - "<T extends ...>"返回类型的意外编译器警告,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27708667/

10-10 19:47