考虑这个尝试实例化某些Lists的Java代码:
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>() { };
Run Code Online (Sandbox Code Playgroud)
list1并且list2很简单; list2在Java 7中使用新的菱形运算符来减少不必要的类型参数重复.
list3是list1使用匿名类的变体,可能会覆盖一些方法ArrayList.
list4尝试使用菱形运算符,类似于list2,但这是一个编译错误,消息'<>'不能与匿名类一起使用.
list5产生一个错误,证明编译器知道实际需要什么类型.错误消息是类型不匹配:无法从新的ArrayList <Integer>(){}转换为List <String>
那么,随着声明list4,为什么钻石运算符不能用于匿名类?这里有一个类似的问题,接受的答案包含JSR-334的以下解释:
不支持使用带有匿名内部类的菱形,因为这样做通常需要扩展类文件签名属性以表示不可表示的类型,事实上的JVM更改.
我需要一些帮助来理解推理.为什么显式类型与相同且明显容易推断的类型需要在生成的类文件中有任何差异?"一般这样做"会涵盖哪些难以处理的用例?
我有一些代码可以写
GenericClass<Foo> foos = new GenericClass<>();
Run Code Online (Sandbox Code Playgroud)
虽然有同事会写
GenericClass<Foo> foos = new GenericClass();
Run Code Online (Sandbox Code Playgroud)
认为在这种情况下,钻石运营商不会增加任何东西.
我知道实际使用与泛型类型相关的参数的构造函数可能会导致编译时错误,<>而不是原始情况下的运行时错误.并且编译时错误要好得多.(如本问题所述)
我也非常清楚编译器(和IDE)可以生成警告,以便将原始类型分配给泛型.
问题是,对于没有参数的情况,或者没有与泛型类型相关的参数.在这种情况下,构造对象是否有任何方式GenericClass<Foo> foos可以根据使用的构造函数而有所不同,或者Javas类型擦除是否保证它们是相同的?
Map<String, Integer> map = new HashMap<String, Integer>();
Run Code Online (Sandbox Code Playgroud)
和
Map<String, Integer> map = new HashMap();
Run Code Online (Sandbox Code Playgroud)
由于这对我来说是新的,我不确定这两个陈述之间的实际区别是什么,因为两者似乎都运行良好.我试图在其他地方找到,但找不到任何具体的答案.
我知道自Java 7以来,在实例化过程中在构造函数中重复泛型类的类型是一种冗余.但是钻石操作员<>怎么样,重复它呢?换句话说,我想知道这有什么区别:
List<String> Fruits = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
还有这个
List<String> Fruits = new ArrayList();
Run Code Online (Sandbox Code Playgroud)
或这个
Map<Integer, String> students = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
还有这个
Map<Integer, String> students = new HashMap();
Run Code Online (Sandbox Code Playgroud)
先感谢您