Java泛型中仅实例化侧使用<>的合法性及作用是什么?
Java允许原始类型变量接收菱形运算符实例化对象的原因及特性
语法合法性的背景
- Java 7 首次引入菱形运算符
<>,核心作用是简化泛型实例化的冗余写法:编译器会根据左侧变量声明的泛型类型自动推断右侧实例的泛型参数,不需要重复写两次类型参数,就是你已经了解的List<String> balloons = new ArrayList<>();这种常规用法。 - 你提到的
List balloons = new ArrayList<>();属于原始类型和菱形运算符的混用写法,Java允许这种写法的核心原因是向后兼容:泛型是JDK 5才新增的特性,为了兼容JDK 5之前完全没有泛型的旧代码,Java一直保留了原始类型(也就是不带泛型参数的集合类型,比如你代码里左侧的List)的语法支持。如果禁止将带<>实例化的对象赋值给原始类型变量,会导致大量旧代码在升级JDK 7及以上版本时编译失败,不符合Java的版本兼容性设计原则。
这种写法中<>的实际作用
这种写法里的<>确实不具备实际的泛型类型校验功能:
- 当左侧变量是原始类型时,编译器做菱形推断没有明确的类型参考,会默认推断泛型参数为
Object,但因为最终实例赋值给了原始类型变量,泛型的编译期类型校验会完全失效。 - 实际使用效果和你直接写
List balloons = new ArrayList();(右侧不带<>)几乎完全一致:你可以向balloons里添加任意类型的对象,编译期不会做类型检查,取出元素时也需要手动强转,没有任何泛型的类型安全保障,唯一的区别是部分编译器会对这种混用写法抛出「使用了未经检查的原始类型」的警告。
开发规范建议
实际项目中不要使用这种混用写法:如果需要用到泛型的类型安全能力,就明确给左侧变量指定泛型参数,配合菱形运算符使用;如果确实需要兼容非常老旧的无泛型代码,直接用原始类型即可,不需要额外加无意义的<>。
内容的提问来源于stack exchange,提问作者Pieter
相关产品推荐
相关产品推荐

