Java8中的模棱两可的重载-ECJ或Javac对吗?

伊恩·罗伯逊

我有以下课程:

import java.util.HashSet;
import java.util.List;

public class OverloadTest<T> extends  HashSet<List<T>> {
  private static final long serialVersionUID = 1L;

  public OverloadTest(OverloadTest<? extends T> other) {}

  public OverloadTest(HashSet<? extends T> source) {}

  private OverloadTest<Object> source;

  public void notAmbigious() {
    OverloadTest<Object> o1 = new OverloadTest<Object>(source);
  }

  public void ambigious() {
    OverloadTest<Object> o2 = new OverloadTest<>(source);
  }
}

这在JDK 7的javac和eclipse(符合性设置为1.7或1.8)下都可以正常编译。但是,尝试在JDK 8的javac下进行编译时,出现以下错误:

[ERROR] src/main/java/OverloadTest.java:[18,35] reference to OverloadTest is ambiguous
[ERROR] both constructor <T>OverloadTest(OverloadTest<? extends T>) in OverloadTest and constructor <T>OverloadTest(java.util.HashSet<? extends T>) in OverloadTest match

请注意,此错误仅适用于ambigous()方法中的构造函数调用,而不适用于方法中的构造函数调用notAmbiguous()唯一的区别是ambiguous()依靠钻石操作员。

我的问题是:在JDK 8下的javac是否正确地标记了一个模糊的解决方案,还是在JDK 7下的javac未能抓住歧义?根据答案,我需要提交一个JDK错误或一个ecj错误。

史蒂夫·K

在调用中,当显式调用T构造函数时,没有歧义:

OverloadTest<Object> o1 = new OverloadTest<Object>(source);

因为T是在构造函数调用时定义的,所以Object传递?在编译时扩展对象检查就可以了,并且没有问题。当T显式设置为Object时,两个构造函数的选择变为:

public OverloadTest(OverloadTest<Object> other) {}
public OverloadTest(HashSet<Object> source) {}

在这种情况下,编译器选择第一个很容易。在另一个示例中(使用菱形运算符),没有显式设置T,因此编译器首先尝试通过检查实际参数的类型来确定T,而第一个选项不需要这样做。

如果更改第二个构造函数以正确反映我想像的是所需的操作(由于OverloadTest是T列表的HashSet,则应该可以传入T列表的HashSet),如下所示:

public OverloadTest(HashSet<List<? extends T>> source) {}

...然后消除歧义。但是就目前而言,当您要求编译器解决该模棱两可的调用时,就会发生冲突。

编译器将看到菱形运算符,并将尝试根据传入的内容以及各种构造函数的期望来解析T。但是HashSet构造函数的编写方式将确保无论传入哪个类,两个构造函数都将保持有效,因为在擦除之后,T始终被Object取代。并且当T为Object时,HashSet构造函数和OverloadTest构造函数具有相似的擦除方式,因为OverloadTest是HashSet的有效实例。并且由于一个构造函数不会覆盖另一个构造函数(因为OverloadTest <T>不会扩展HashSet <T>),因此实际上不能说一个构造函数比另一个构造函数更具体,因此它不知道如何做出选择,而是抛出编译错误。

只会发生这种情况是因为使用T作为边界,您正在强制编译器进行类型检查。如果您只是将它做成<?>而不是<?扩展T>它将编译就好了。Java 8编译器在类型和擦除方面比Java 7更为严格,部分原因是Java 8中的许多新功能(例如接口防御程序方法)要求它们对泛型有一点点学问。Java 7没有正确报告这些情况。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

无效的方法引用/模棱两可的引用(javac / ecj行为差异)

来自分类Dev

这些重载难道不是模棱两可的吗?

来自分类Dev

SFINAE不能防止模棱两可的运算符重载吗?

来自分类Dev

这实际上是模棱两可的吗?

来自分类Dev

Prolog的句子可以模棱两可吗?

来自分类Dev

MSVC-C2668对重载函数的模棱两可的调用-它是编译器错误吗?

来自分类Dev

我正在尝试在C ++ 03中嵌套boost的“ map_list_of”,但显然构造是模棱两可的吗?

来自分类Dev

参数过载明显的模棱两可-仍然可以编译并正常工作吗?

来自分类Dev

ls实用程序无法解释模棱两可的文件引用吗?

来自分类Dev

'std :: cin >>'中'operator >>'的模棱两可的重载

来自分类Dev

Java ==行为模棱两可

来自分类Dev

错误:对重载函数的模棱两可的调用

来自分类Dev

为什么此方法重载模棱两可?

来自分类Dev

C ++模板,模棱两可的重载

来自分类Dev

矩阵加法:“ operator +”的模棱两可的重载

来自分类Dev

错误:“运算符==”的模棱两可的重载

来自分类Dev

C ++ libconfig模棱两可的重载

来自分类Dev

模棱两可的呼叫的默认重载

来自分类Dev

矩阵加法:“ operator +”的模棱两可的重载

来自分类Dev

C ++ libconfig模棱两可的重载

来自分类Dev

VC ++ 2012中意外的模棱两可的重载解决方案

来自分类Dev

gcc中的模棱两可的重载,与msvc一起使用

来自分类Dev

C ++中的重载函数为unsigned char和unsigned int导致模棱两可

来自分类Dev

C ++中的重载函数为unsigned char和unsigned int导致模棱两可

来自分类Dev

为什么IDEA导入模棱两可的Java

来自分类Dev

Java 8 Lambda模棱两可的可运行和回调

来自分类Dev

xpath [last()]方法中的模棱两可的错误

来自分类Dev

Lang和requestLang中的模棱两可的值

来自分类Dev

在C#中返回模棱两可的对象

Related 相关文章

  1. 1

    无效的方法引用/模棱两可的引用(javac / ecj行为差异)

  2. 2

    这些重载难道不是模棱两可的吗?

  3. 3

    SFINAE不能防止模棱两可的运算符重载吗?

  4. 4

    这实际上是模棱两可的吗?

  5. 5

    Prolog的句子可以模棱两可吗?

  6. 6

    MSVC-C2668对重载函数的模棱两可的调用-它是编译器错误吗?

  7. 7

    我正在尝试在C ++ 03中嵌套boost的“ map_list_of”,但显然构造是模棱两可的吗?

  8. 8

    参数过载明显的模棱两可-仍然可以编译并正常工作吗?

  9. 9

    ls实用程序无法解释模棱两可的文件引用吗?

  10. 10

    'std :: cin >>'中'operator >>'的模棱两可的重载

  11. 11

    Java ==行为模棱两可

  12. 12

    错误:对重载函数的模棱两可的调用

  13. 13

    为什么此方法重载模棱两可?

  14. 14

    C ++模板,模棱两可的重载

  15. 15

    矩阵加法:“ operator +”的模棱两可的重载

  16. 16

    错误:“运算符==”的模棱两可的重载

  17. 17

    C ++ libconfig模棱两可的重载

  18. 18

    模棱两可的呼叫的默认重载

  19. 19

    矩阵加法:“ operator +”的模棱两可的重载

  20. 20

    C ++ libconfig模棱两可的重载

  21. 21

    VC ++ 2012中意外的模棱两可的重载解决方案

  22. 22

    gcc中的模棱两可的重载,与msvc一起使用

  23. 23

    C ++中的重载函数为unsigned char和unsigned int导致模棱两可

  24. 24

    C ++中的重载函数为unsigned char和unsigned int导致模棱两可

  25. 25

    为什么IDEA导入模棱两可的Java

  26. 26

    Java 8 Lambda模棱两可的可运行和回调

  27. 27

    xpath [last()]方法中的模棱两可的错误

  28. 28

    Lang和requestLang中的模棱两可的值

  29. 29

    在C#中返回模棱两可的对象

热门标签

归档