【发布时间】:2020-02-13 14:56:32
【问题描述】:
我有以下 Java 类(带有嵌套类/接口)。从 Eclipse(版本:2019-09 R (4.13.0))中运行 main 方法时,我得到以下输出:
java.version: 1.8.0_241
PageA.m3() called
这是 Eclipse 使用的命令行:
/Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:52180 -javaagent:/Users/*****/eclipse/java-2019-09/Eclipse.app/Contents/Eclipse/configuration/org.eclipse.osgi/222/0/.cp/lib/javaagent-shaded.jar -Dfile.encoding=UTF-8 -classpath <a-list-of-.jar-files> _play.PageTest
在 Intellij(IDEA 2019.3.3(社区版))中运行相同的代码时,我得到以下输出:
src/main/java/_play/PageTest.java:13: error: reference to m1 is ambiguous
.m1(pageAorB -> ((SpecialPage<?>) pageAorB).m3());
^
both method m1(Consumer<T#1>) in Page and method m1(Consumer<T#2>) in AbstractPage match
where T#1,T#2 are type-variables:
T#1 extends Page<T#1> declared in interface Page
T#2 extends Page<T#2> declared in class AbstractPage
为什么我在 Intellij 中出现此错误,但在 Eclipse 中却没有?有没有办法解决这个问题,让它在 Intellij 中运行而不会出错?
这是 Java 类:
package _play;
import java.util.function.Consumer;
import java.util.function.Function;
public class PageTest {
public static void main(String[] args) {
System.out.println("java.version: " + System.getProperty("java.version"));
new PageC()
.m2(pageC -> (1 == 1 ? new PageA() : new PageB()))
.m1(pageAorB -> ((SpecialPage<?>) pageAorB).m3());
}
public static interface Page<T extends Page<T>> {
T m1(Consumer<T> c);
<R> R m2(Function<? super T, ? extends R> f);
}
public static abstract class AbstractPage<T extends Page<T>> implements Page<T>{
@Override
public T m1(Consumer<T> c){
c.accept(self());
return self();
}
@Override
public final <R> R m2(Function<? super T, ? extends R> f) {
return f.apply(self());
}
abstract protected T self();
}
public static interface SpecialPage<T extends Page<T>> extends Page<T> {
T m3();
}
public static class PageC extends AbstractPage<PageC> {
@Override
protected PageC self() {
return this;
}
}
public static class PageB extends AbstractPage<PageB> implements SpecialPage<PageB> {
@Override
public PageB m3() {
System.out.println("PageB.m3() called");
return this;
}
@Override
public PageB self() {
return this;
}
}
public static class PageA extends AbstractPage<PageA> implements SpecialPage<PageA> {
@Override
public PageA m3() {
System.out.println("PageA.m3() called");
return this;
}
@Override
public PageA self() {
return this;
}
}
}
编辑 在这种情况下,Page 接口和 AbstractPage 类位于客户端无法更改的库中。但是客户端应该能够扩展 Page 接口。
【问题讨论】:
-
您使用的是 Maven 还是 Gradle?可以试试命令行吗?
-
Gradle。我会尝试命令行...并报告。
-
从 gradle 命令行运行(使用类型为 JavaExec 的任务)我得到与 Intellij 中相同的错误
-
在 Eclipse 中运行时,使用的命令行是什么?它应该在输出窗口中,您可以将其添加到问题中吗?否则不可能知道项目是如何在 IDE 中运行的。
-
问题是,是Eclipse编译器(4.13)还是
javac(1.8.0_241)对(“Eclipse使用的命令行”是运行它,不要编译它,在这里没关系)。我猜,因为这里的T相同,所以Eclipse 是对的(interface Page<T extends Page<T>>可以简化为interface Page<T>和AbstractPage<T extends Page<T>> implements Page<T>到AbstractPage<T> implements Page<T>,对吧?)。 @鲍里斯@etxalpo
标签: eclipse generics intellij-idea javac ecj