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 应变克难开新局 7904614
- 2 外交部回应美批准对华出售H200芯片 7808381
- 3 日本气象厅:一周内或发生9级地震 7712096
- 4 “好房子”长啥样 7616664
- 5 你点的三家外卖可能出自同一口锅 7519613
- 6 日舰曾收到中方提示 7425683
- 7 中方回应向日本出口稀土出现延误 7334281
- 8 受贿超11亿!白天辉被执行死刑 7231816
- 9 音频实证日本有意滋扰中方训练 7137889
- 10 入冬以来最大范围风雪天气来了 7046305




![香草帕露露 集齐十张会动的香草[开学季] 广东的夏天就会回来啦~[开学季][开学季][开学季] ](https://imgs.knowsafe.com:8087/img/aideep/2021/11/27/35e38a5a81ea18a201aca8c81f1be14a.jpg?w=250)
![aangelinawwnighty nighty[二哈]2深圳 ](https://imgs.knowsafe.com:8087/img/aideep/2022/6/4/4f16c494172301d9dd7238153aa4cad6.jpg?w=250)




CSDN
