使用eclipse进行代码编译,但不使用javac进行代码编译

问题描述 投票:2回答:3

下面的代码在Eclipse编译时没有任何错误,但是在Javac中生成了一个错误。似乎是编译器错误,但我不知道哪一个是正确的。

我想指出的是,我知道如何通过更改代码以使其同时适用于此错误来纠正此错误,但这不是当前主题。我只想知道是Java还是Eclipse问题。

我尝试使用Intellij,但遇到相同的javac错误。

重现此错误的示例代码:

import java.util.ArrayList;
import java.util.List;

public class A<T extends B> {
    protected List<C> list = new ArrayList<>();

    class C {}

    public void createIO() {
        A<? extends B> x = null;
        List<A<? extends B>.C> y = x.list;
    }
}

class B {
}

JVM:

openjdk version "13-BellSoft" 2019-09-17
OpenJDK Runtime Environment (build 13-BellSoft+33)
OpenJDK 64-Bit Server VM (build 13-BellSoft+33, mixed mode, sharing)

使用Eclipse,我没有任何错误。使用Javac,我有error

A.java:13: error: incompatible types: List<A<CAP#1>.C> cannot be converted to List<A<? extends B>.C>
        List<A<? extends B>.C> y = x.list;
                                    ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends B from capture of ? extends B
java eclipse compilation javac ecj
3个回答
0
投票

这看起来像是[javac的错误,因为这两种类型都兼容:两者都引用了C的内部类A,并带有B的通用参数或扩展了[ C0]。

您可以通过将B替换为? extends B来简化代码(或者,如果您不仅要使用列表元素使用B来替换B -specif,还希望使用T来替换T -specific东西),也可以用javac编译而没有问题。请注意,集合Collection<Foo>可以包含Foo类型的元素以及扩展了Foo类型的元素。

public void createIO() { A<B> x = null; List<A<B>.C> y = x.list; }

这里是another example where the Eclipse Java compiler and javac differ

0
投票
可能是Idea和Eclipse使用他们自己的编译器。

0
投票
我不认为这是一个错误。

编译器知道javac的参数类型必须是List的实例化:

C

并且A<? extends B>.C>
               ^
的参数类型必须是A的子类型,但是它仍然不确切地知道哪个实例化。

长话短说,B,您可以按以下步骤修复代码:

generics aren't covariant

© www.soinside.com 2019 - 2024. All rights reserved.