Java新特性:数据类型可以扔掉了?



枚举:尽管在 JDK 5 中增加了枚举类型,但是 Class 文件常量池的 CONSTANT_Class_info 类型常量并没有发生任何语义变化,仍然是代表一个类或接口的符号引用,没有加入枚举,也没有增加过“CONSTANT_Enum_info”之类的“枚举符号引用”常量。所以使用 enum 关键字定义常量,尽管从 Java 语法上看起来与使用 class 关键字定义类、使用 interface 关键字定义接口是同一层次的,但实际上这是由 Javac 编译器做出来的假象,从字节码的角度来看,枚举仅仅是一个继承于 java.lang.Enum、自动生成了 values() 和 valueOf() 方法的普通 Java 类而已,因此枚举也归为引用类型了。

使用对比
场景一:定义字符串
String?str?=?"Hello,?Java.";
var?s?=?"Hello,?Java.";
PS:这里的旧写法指的是 JDK 10 之前的版本,而新写法指的是 JDK 10 以后(包含 JDK 10)的版本。
场景二:数值相加
int?num1?=?111;
double?num2?=?555.666d;
double?num3?=?num1?+?num2;
System.out.println(num3);
PS:当遇到不同类型相加时(int+ double)会发生数据类型向上转型,因此 num3 就会升级为 double 类型。
var?n1?=?111L;
var?n2?=?555.666;
var?n3?=?n1?+?n2;
System.out.println(n3);
场景三:集合
List<Object>?list?=?new?ArrayList<>();
list.add("Hello");
list.add("Java");
var?list?=?new?ArrayList<>();
list.add("Hello");
list.add("Java");
场景四:循环
for?(Object?item?:?list)?{
????System.out.println("item:"?+?item);
}
for?(int?i?=?0;?i?<?10;?i++)?{
????//?do?something...
}
for?(var?item?:?list)?{
????System.out.println("item:"?+?item);
}
for?(var?i?=?0;?i?<?10;?i++)?{
????//?do?something...
}
场景五:配合 Lambda 使用
List<Object>?flist?=?list.stream().filter(v?->
????????????????v.equals("Java")).collect(Collectors.toList());
System.out.println(flist);
var?flist?=?list.stream().filter(v?->
?????????????v.equals("Java")).collect(Collectors.toList());
System.out.println(flist);

优点分析
① 提高了可读性
InternationalCustomerOrderProcessor<AnonymousCustomer,?SimpleOrder<Book>>?orderProcessor?=?
????createInternationalOrderProcessor(customer,?order);
var?orderProcessor?=?createInternationalOrderProcessor(customer,?order);
② 命名对齐
//?显式类型
No?no?=?new?No();
AmountIncrease<BigDecimal>?more?=?new?BigDecimalAmountIncrease();
HorizontalConnection<LinePosition,?LinePosition>?jumping?=
??new?HorizontalLinePositionConnection();
Variable?variable?=?new?Constant(6);
List<String>?names?=?List.of("Java",?"中文社群");
var?no?=?new?No();
var?more?=?new?BigDecimalAmountIncrease();
var?jumping?=?new?HorizontalLinePositionConnection();
var?variable?=?new?Constant(6);
var?names?=?List.of("Java",?"中文社群");

使用规则 & 反例
它只能用于局部变量上; 声明时必须初始化; 不能用作方法参数和全局变量(类变量)。
PS:因为 var 的实现必须根据等会右边的代码进行类型推断,因此它不能被赋值 null 或不被初始化。
反例一:未初始化和赋值 null


反例二:中途类型更改

反例三:全局变量

反例四:作为返回值


原理分析

然后我们再用反编译工具打开被编译的类发现:var 竟然被替换成一个个确定的数据类型了,如下图所示:

由此我们可以得出结论:var 关键字的实现和它的名字密切相关, var 只是局部类型推断,它只会在 Java 编码期和编译期有效,当类被编译为 class 文件时,var 就会变成一个个确定的数据类型(通过推断得出)。所以我们可以把 var 通俗的理解为 Java 的语法糖,使用它可以让我们快速优雅的实现业务代码,但 var 在字节码层面是不存在的。

总结


更多精彩推荐
?荣耀与美团合作推出 “共享笔记本”;传腾讯建议推出美国版微信,已被否;Debian 10.6 稳定版发布|极客头条
?秋天的第一杯奶茶该买哪家?Python 爬取美团网红奶茶店告诉你
?区块链+生鲜:杜绝“偷梁换柱”和“以次充好”
点分享 点点赞 点在看
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 习近平将发表二〇二六年新年贺词 7904141
- 2 2026年国补政策来了 7808738
- 3 东部战区:开火!开火!全部命中! 7712893
- 4 2026年这些民生政策将惠及百姓 7616985
- 5 小学食堂米线过期2.5小时被罚5万 7519709
- 6 解放军喊话驱离台军 原声曝光 7428214
- 7 为博流量直播踩烈士陵墓?绝不姑息 7327605
- 8 每月最高800元!多地发放养老消费券 7238391
- 9 数字人民币升级 1月1日起将计付利息 7141831
- 10 2026年1月1日起 一批新规将施行 7040675











CSDN
