当前位置: 首页 > 知识库问答 >
问题:

为什么Java7菱形操作符不能用于匿名类?

璩涛
2023-03-14

考虑这个java代码,它试图实例化一些<代码>列表< /C>

List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<>();
List<String> list3 = new ArrayList<String>() { };
List<String> list4 = new ArrayList<>() { };
List<String> list5 = new ArrayList<Integer>() { };

list1list2很简单;list2在Java7中使用新的菱形运算符来减少类型参数的不必要重复。

list3是使用匿名类的list1的变体,可能会重写ArrayList的某些方法。

试图使用菱形运算符,类似于list2,但这是一个编译错误

list5产生一个错误,证明编译器知道实际需要什么类型。错误消息是类型不匹配:无法从新ArrayList转换

那么,有了list4的声明,为什么菱形运算符不能与匿名类一起使用呢?这里有一个类似的问题,一个公认的答案包含JSR-334的以下解释:

不支持将diamond与匿名内部类一起使用,因为这样做通常需要对class file signature属性进行扩展,以表示不可表示的类型,这是事实上的JVM更改。

我需要一些帮助来理解这种推理。为什么显式类型与相同且显然易于推断的类型在生成的类文件中需要任何差异?“一般情况下这样做”将涵盖哪些困难的用例?

共有3个答案

彭硕
2023-03-14

您可以使用它在java 9示例钻石操作符

 MyHandler<Integer> intHandler = new MyHandler<>(1) {

        @Override
        public void handle() {
            // handling code...
        }
 };
施超
2023-03-14

您可以在Java9中使用diamond Operator

MyHandler<Integer> intHandler = new MyHandler<>(1) {

        @Override
        public void handle() {
            // handling code...
        }
    };

    MyHandler<? extends Integer> intHandler1 = new MyHandler<>(10) {

        @Override
        void handle() {
            // handling code...
        }
    };

    MyHandler<?> handler = new MyHandler<>("One hundred") {

        @Override
        void handle() {
            // handling code...
        }
    };
}
阎功
2023-03-14

“硬币计划”邮件列表中对此进行了讨论。实质上(我的重点):

在内部,Java编译器操作的类型集比可以在Java程序中显式编写的类型集更丰富。不能在Java程序中编写的编译器内部类型称为非可表示类型。由于diamond使用的推理,可能会出现不可表示的类型。因此,不支持将diamond与匿名内部类一起使用,因为这样做通常需要对class file signature属性进行扩展,以表示不可表示的类型,这是事实上的JVM更改。未来的平台版本可以允许在创建匿名内部类时使用diamond,只要推断的类型是可表示的。

请注意,Java8中也不支持它,但将作为新功能包含在Java9中(“铣削项目硬币”第3项)。

 类似资料:
  • java 7中的菱形运算符允许以下代码: 然而,在Java 5/6中,我可以简单地编写: 我对类型擦除的理解是,它们完全相同。(无论如何,泛型会在运行时被删除)。 为什么要为钻石而烦恼呢?它允许哪些新功能/类型的安全性?如果它不能产生任何新的功能,为什么他们会把它作为一个功能提出来?我对这个概念的理解有缺陷吗?

  • 问题内容: 考虑下面的Java代码,它尝试实例化一些: 并且很简单;在Java 7中使用新的Diamond运算符来减少不必要的类型参数重复。 是使用匿名类的一种变体,可能会覆盖的某些方法。 尝试使用菱形运算符,类似于,但这是编译错误,消息 “ <>”不能与匿名类一起使用。 产生一个错误,证明编译器知道实际需要的类型。错误消息是 类型不匹配:无法从新的ArrayList (){}转换为List 因此

  • 代码如下: 运行时,这是错误消息: 错误:不匹配'运算符*'(操作数类型是'std::__cxx11::字符串{aka std::__cxx11::basic_string 如何修复此错误并使程序正确运行?

  • 问题内容: 我有一个类型为Patient_class的arraylist,并且用黄色下划线标出了arraylist类型,IDE提到了“新表达式中的冗余类型参数(使用菱形运算符)”。 我的问题是:我应该改用菱形运算符吗?是必须的吗?将记录存储到arraylist时,是否会丢失数据或出现其他任何问题? 这是我的数组列表: 老实说,我不知道钻石经营者实际上是什么。 问题答案: Diamond运算符的目的

  • 问题内容: 在Java 7和更高版本中,菱形通常可以像这样毫无问题地用于推断类型: 但是,它不能用于这样的匿名内部类: 为什么是这样?从逻辑上讲,在这种情况下,我绝对可以将类型推断为。做出该决定的逻辑上的理由是,实际上不能在匿名内部类上推断类型,还是出于其他原因而将其省略了? 问题答案: 在JSR-334中: 不支持将Diamond与匿名内部类一起使用,因为这样做通常需要扩展类文件签名属性以表示不