【问题标题】:Java generic compile time error migrating from Java 6 to 7 or 8从 Java 6 迁移到 7 或 8 的 Java 通用编译时错误
【发布时间】:2016-05-23 20:03:33
【问题描述】:

我们已经开始在使用泛型并且在 Java 6 下成功编译的代码上出现编译错误。这里有一个简单的类来重现:

class Test {
    static class Foo<T> {
            T t;
            Foo(T t) { this.t = t; }
            T get() { return t; }
    }

    static class Bar extends Foo<Long> {
            Bar(Long t) { super(t); }
    }

    static class Foobar<N extends Number> extends Bar {
            Foobar() { super(5L); }
    }

    public static void main(String[] args) {
            Bar bar = new Bar(0L);
            Long b = bar.get();             // This works
            Foobar foobar = new Foobar();
            Long fb = foobar.get(); // This generates a compile time error
    }
}

产生的错误是:

Test.java:26: error: incompatible types: Object cannot be converted to Long
            Long fb = foobar.get(); // This generates a compile time error

有人有什么想法吗?

【问题讨论】:

  • 对不起,没有提到编译错误发生在 Java 7 和 8,但不是在 6...
  • 奇怪的是,虽然我从命令行使用 jdk1.7.0_13 得到这个编译错误,但这段代码在 Eclipse 中编译得很好,使用相同的编译器(仔细检查“安装的 JRE”是否指向相同的路径,合规级别为 1.7,并使用该 jdk)。
  • 我得到了完全一样的 - Eclipse 用 1.8 集编译这个没有错误。很奇怪……

标签: java generics compilation compiler-errors


【解决方案1】:

这是因为没有任何类型参数的Foobar 是一个原始类型。原始类型没有通用能力,因此在这种情况下,原始类型 Foobar 扩展了 Bar,它扩展了 raw 类型 Foo。原始类型使用其参数的上限,因为它们在擦除后以这种方式编译,并且编译器没有类型参数来安全地插入强制转换。

对于Foo,这个上限是Object。这导致Foo.get() 返回Object,所以Bar.get() 返回Object,所以Foobar.get() 也返回Object。显然,编译器不会将 Object 转换为 Long 而不进行显式转换。

相比之下,参数化类型Foobar&lt;N&gt; 扩展了Bar,后者扩展了参数化类型Foo&lt;Long&gt;。编译器现在可以使用泛型,所以它看到Foo&lt;T&gt;.get() 的类型为TFoo&lt;Long&gt;.get() 的类型为LongBar.get() 的类型为Long,最后Foobar&lt;N&gt;.get() 的类型为@987654345 @ 也一样。

这意味着你应该声明foobar,如下所示:

Foobar<...> foobar = new Foobar<...>();

foobar 的类型参数是什么并不重要,只要它存在即可。它甚至可以是通配符?

【讨论】:

  • 但是,为什么原始类型在 1.6 中有效?我不知道 1.7 对泛型的任何更改(除了类型推断)
  • @radoh 我认为他们只是在 7 中使类型检查更加严格。现代代码中不应该存在原始类型,它们只是为了兼容性而存在,即使调用代码是使用泛型更新的类型不。不过不确定,最好只查看 Oracle 的发行说明。
  • 感谢您的解释,我个人认为 Java 6 的方式更直观,而所需的更改意味着代码必须更冗长。不带参数定义的泛型类型实例实际上应该被视为基本参数,在这种情况下,Foobar 本身应该与 Foobar...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-12
  • 2019-06-06
  • 2018-03-25
  • 2011-11-02
相关资源
最近更新 更多