- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
考虑以下 returnsNull
函数并使用泛型类型调用它:
public static <T> List<T> returnNull(Class<? extends T> clazz) {
return null;
}
public static void main( String[] args )
{
List<AtomicReference<?>> l = returnNull(AtomicReference.class);
}
Eclipse 编译器在设置为 Java 8 时接受它,但是 javac
在 Java 8 中拒绝它:
incompatible types: cannot infer type-variable(s) T
(argument mismatch; java.lang.Class<java.util.concurrent.atomic.AtomicReference> cannot be converted to java.lang.Class<? extends java.util.concurrent.atomic.AtomicReference<?>>)
潜在的区别似乎是给定两个参数化类型 P1<T>
和 P2<T>
,Eclipse 允许从使用原始内部类型参数化的外部类型进行转换:P1<P2>
到用内部类型的下界参数化的外部类型,带有无限通配符,如 P1<? extends P2<?>>
. javac
没有。
这不仅仅是理论上的思考:如果此代码被接受,它将解决我的 generics filtering problem .
谁是对的?
最佳答案
期间 applicability inference 欧洲法院推断<T>
至 AtomicReference#RAW
, 让我们签名 returnNull
显示为
List<AtomicReference#RAW> returnNull(Class<? extends AtomicReference#RAW>)
具体步骤是:
⟨Class<AtomicReference#RAW> → Class<? extends T#0>⟩
⟨Class<AtomicReference#RAW> <: Class<? extends T#0>⟩
⟨AtomicReference#RAW <= ? extends T#0⟩
⟨AtomicReference#RAW <: T#0⟩
AtomicReference#RAW <: T#0
T#0 = AtomicReference#RAW
现在,传递 Class<AtomicReference#RAW>
类型的值没有问题了进入那个方法。
(后缀 #RAW 是原始类型的特定于实现的表示,为清楚起见在此处复制)。
编辑: invocation type inference 期间情况看起来不同:通过将目标类型添加到混合中,我们最终(在 incorporation 期间)具有以下约束:
⟨AtomicReference#RAW <: AtomicReference<?>⟩
此约束应减少为 FALSE,但 ecj 减少为 TRUE。由此看来,拒绝该方案似乎是正确的答案。
我提交了 bug 528970以便欧洲法院进一步调查。
这有点讽刺意味,因为 javac has a long standing bug它错误地假设T#RAW <: T<X>
.出于兼容性原因,ECJ 明确地将此错误复制到许多位置,但显然在一个特定的代码位置是相反的:javac 在 ECJ 检查兼容性的地方应用子类型。
编辑 2: 一年后,ECJ 中的错误似乎只能在 JLS 在 JDK-8054721 及其周围得到改进后才能修复。 .
关于java - Eclipse ECJ 接受此代码,javac 不接受 - 谁是对的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47662493/
以下代码创建了一个Collector,它产生了一个UnmodifiableSortedSet: package com.stackoverflow; import java.util.Collecti
我正在使用 ECJ(一种进化算法包),我想调用扩展类中的某些变量,但我不知道如何从问题类中获取它们。 正如您在下面的问题类中看到的,我希望能够在 NetworkGene 类中调用变量 x,但它不起作用
我对 Java 的类型推断有疑问。我使用的是 javac 1.8.0_121,以下代码可以使用 Eclipse ECJ 进行编译,但不能使用 javac import java.util.functi
EJC(Eclipse 的内部 Java 编译器)中有一个错误,我不想等待官方错误修复。有没有办法将现有的 Eclipse 安装(假设是 4.6)指向 4.7 beta 的 ECJ 版本? 我知道,我
使用遗传编程 ECJ 21 ,我正在寻找有关如何序列化 ec.Individual(在成功(?)进化之后)的建议。 诀窍是,然后我需要在稍后阶段反序列化这个 GP,然后执行它......最好在 ECJ
我有一个小问题,在 eclipse 中编译的某些 java 类与由独立 ecj(来自相同的源代码)编译的类略有不同。如何找到 eclipse 正在使用的 ecj 版本? (我假设这就是区别所在) 最佳
注意:这篇文章不是关于 eclipse 创建的用于 java 的 eclipse 编译器——只是为了确保不会造成混淆。 我正在尝试让 ecj 遗传学编程系统在 Windows 上的 eclipse k
我对 elipse.jdt.core 插件做了一些更改,以支持类似于 Java 的语言(MaxJ)。我所做的更改可以在这里找到: https://github.com/maxeler/eclipse.
我有以下代码: package test; import java.util.stream.IntStream; public class A { public static void mai
考虑以下 returnsNull函数并使用泛型类型调用它: public static List returnNull(Class clazz) { return null; } publi
我有以下类(class): import java.util.HashSet; import java.util.List; public class OverloadTest extends Ha
当编译一个 Client 时,它使用接口(interface) I 的某些实现(例如 O),I 的类文件code> 也必须出现在类路径中。奇怪的是,这只是 javac 的情况,因为 Eclipse 编
Eclipse 使用它自己的编译器 (ECJ) 来编译 Java 代码。调试使用 Eclipse 编译的程序更容易,因为可以立即应用简单的代码更改(通过热代码替换)。 另一方面,Maven 使用(默认
今天遇到这个问题,花了很长时间试图重现/弄清楚发生了什么。有人可以解释为什么会发生这种情况,或者这是类型删除/默认方法/lambda/多态性的错误吗?取消对默认方法的注释使其运行良好,但我希望它能按原
我正在运行 1 个生产者线程、1 个消费者线程问题,共享缓冲区和临时缓存(包含 1000 个元素)。 eclipse 执行 (ECJ) 使用 33% 的 CPU(1 个内核用于生产者,1 个用于消费者
尝试运行 hello world grails 应用程序。 我收到此错误: | Error Failed to resolve dependencies (Set log level to 'warn
在 JRE 1.7 中运行时,我从 ECJ(版本 4.2.1)编译器获得 NPE,而同一项目在 JRE 1.6 上可以正确编译。 CompilationProgress 监视器显示总共有 2493 个
尝试运行以下组合: Maven (3.6.1) OpenJDK 11 使用 module-info.java Fails with the following error message: [ERRO
您好 friend ,我是android studio上的新手,安装后我发现问题gradle构建失败,因为 错误:无法下载ecj.jar(org.eclipse.jdt.core.compiler:e
我有一个可以通过 eclipse(ECJ)很好地构建的项目但是 Oracle javac 无法构建它(某些原因,如链接the different of ecj and javac所示)。 我想从ecl
我是一名优秀的程序员,十分优秀!