- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
给出以下类:
public class FooTest {
public static class Base {
}
public static class Derived extends Base {
}
public interface Service<T extends Base> {
void service(T value);
}
public abstract class AbstractService<T extends Derived> implements Service<T> {
public void service(T value) {
}
}
private AbstractService service;
public void bar(Base base) {
if(base instanceof Derived) {
service.service(base); // compile error at this line
}
}
}
使用以下 pom.xml
构建类时:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mgm-tp</groupId>
<artifactId>java-compiler-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerId>eclipse</compilerId>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-eclipse</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
在 maven 3.4 中它会产生以下编译错误:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile (default-compile) on project java-compiler-test: Compilation failure [ERROR] C:\Users\abrieg\workingcopy\java-compiler-test\src\main\java\FooTest.java:[25] The method service(FooTest.Base) in the type FooTest.Service is not applicable for the arguments (FooTest.Base)
当将 eclipse 编译器的源和目标级别设置为 1.7 或使用 javac
作为编译器时,不会报告编译错误。
问题是 JLS 1.8 是否在类型推断方面更具体,以致于 java 1.8 的 eclipse 编译器实际上不允许此代码,或者这是否是 eclipse 编译器中的回归。
根据编译器错误的文本,我倾向于说它是回归,但我不确定。
我已经确定了以下两个已报告给 jdt 的错误,但我认为它们并不完全适用:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=432603 https://bugs.eclipse.org/bugs/show_bug.cgi?id=430987
如果这是回归,是否已经向 jdt 报告过?
最佳答案
据我所知,这段代码应该可以编译,但当然不是没有未经检查的警告。
你声明了一个变量service
原始类型 AbstractService
这是原始类型的子类型Service
它有一个方法 void service(Base)
这是void service(T)
的删除.
所以调用service.service(base)
可以调用该方法 void service(Base)
在 Service
中声明,当然,带有未检查警告,因为该方法是通用的,并且没有验证类型参数 T
发生了。
这可能是违反直觉的类型 AbstractService
使用删除为 void service(Derived)
的方法覆盖该方法但是这个方法只能在通用上下文中覆盖另一个方法,而不是在原始类型继承关系中。
或者,换句话说,类型不能以比被覆盖的父类(super class)型方法对参数类型有更多限制的方式覆盖方法。
这也适用于通用类型继承,但结果不同。如果您的变量类型为 AbstractService<X>
, 然后 X
必须可分配给 Derived
由于类型参数的约束。此类型 AbstractService<X>
是 Service<X>
的子类型它有一个方法 void service(X)
(如 T
:= X
)被 AbstractService<X>
覆盖(实现)用一种方法 void service(X)
它接受相同的参数类型。
由于您的网站上似乎有些困惑,我想强调这与您的if(… instanceof Derived)
无关。陈述。如上所述,此行为是由于使用了原始类型,这意味着您正在使用 AbstractService
没有实际的类型参数并且基本上关闭了泛型类型检查。如果你写了,这甚至会起作用
public void bar(Base base) {
service.service(base); // UNCHECKED invocation
}
如果您将变量的声明更改为
private AbstractService<Derived> service;
它不再是原始类型,类型检查将会发生并且service.service(base)
将产生一个编译器错误,无论你是否用 if(base instanceof Derived) { … }
将其括起来还是不是。
原始类型 的存在只是为了与泛型之前的代码兼容,您应该避免使用它们,并且不要忽略因使用原始类型 而引发的警告。
关于java - 以下代码是否应该在 Java 1.8 下编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29700417/
这个问题在这里已经有了答案: standalone parentheses in javascript [duplicate] (5 个答案) 关闭 8 年前。 我在学习JavaScript,有时会
我是mysql新手,我必须减少以下更新查询的执行时间 UPDATE temp_countcalculations, ( SELECT count(*) as insuffcounts,CRP_
def escape_html(s): for (i, o) in (("&","&"),(">", ">"),(" "变成 ">"等。 关于python - 以下 for 循环
if (read(read(cin, data1), data2)) 问题是C++ Primer 5th Edition 的练习。 read 函数定义如下: std::istream &read(st
我想创建两个宏。其中一个将扩展到函数原型(prototype)和函数内容,另一个将扩展到仅函数原型(prototype)。我正在考虑创建以下内容: #ifdef SOME_CONDITION #def
我正在使用 jongo API - org.jongo.MongoCollection 是类。 我有对象 ID 列表并转换为与 ObjectId[] 相同并尝试按如下方式查询 collection.f
有人可以解释以下正则表达式匹配什么吗? ^.*$ 谢谢! 最佳答案 或者整个字符串或者整行,取决于是否multiline mode被使用。 关于java - 以下 ^.*$ 正则表达式匹配什么?,我们
#include void main() { int a,b,c; for(b = c = 10; a = "- FIGURE?, UMKC,XYZHello Folks,TFy!QJ
我的代码段中的以下代码行被 Sonar 检测为问题。 代码段: final int Pending=1; Sonar 问题: Name 'Pending' must matc
Print name of all activities with neither maximum nor minimum number of participants 我尝试了以下查询,但出现错误:
这个问题在这里已经有了答案: What is this practice called in JavaScript? (7 个回答) 关闭8年前。 (function() { //do stuff
根据任务,我们必须通过 foldr 实现 foldl。通过比较函数签名和 foldl 实现,我得到了以下解决方案: myFoldl :: (a -> b -> a) -> a -> [b] -> a
这个问题在这里已经有了答案: Export an es6 default class inline with definition or at end of file? (1 个回答) 关闭 2 年
据我了解,以下是相同的: Person p{}; // Case 1 Person p = {}; // Case 1.5 我注意到 Person p = Person{}; // Case 2 产生
below i have given a javascript code picture `` can any one help me in this code. what do this code.
我想在标题和正文上搜索全文,并在答案计数上进行过滤。 我阅读了elasticsearch documentation for combining filters并构建了此查询。 "query": {
它是流动的 C 代码中的内存泄漏吗? #include int *a; int main() { a = malloc(sizeof(int)*10); return
这两个声明有什么区别: char (*ptr)[N]; 对比 char ptr[][N]; 谢谢。 最佳答案 (1)声明 char (*ptr)[N]; ptr 是指向大小为 N 的字符数组的指针 下
data II = I Int Int deriving (Show) instance II Show where show I a b = show (a+b) showt.hs:3:2: s
我从 clojuredoc 中阅读了关于 condp 的文档。在文档中我找到了以下代码: (condp 一些 [1 2 3 4] #{0 6 7} :>> 公司 #{4 5 9} :>> 十二月 #{
我是一名优秀的程序员,十分优秀!