Java中的语法糖
语法糖的定义:语法糖指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,并没有给语言添加什么新东西,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。(也可以认为语法糖就是把一段复杂的代码简化成更精简的代码)
在这里就介绍java中几个常用的语法糖:
1.foreach
foreach又被叫做增强for循环,常被用于替换一般的for (int i = 0; i < ; i++),这样形式的循环,应用场景是当使用者不关注循环中的i值时。
下面是demo:
for (String temp : args) {
//doSomething
}
List<String> list = new LinkedList<>();
for (String temp : list) {
//doSomething
}
编译后:
String[] var1 = args;
int var2 = args.length;
for(int var3 = 0; var3 < var2; ++var3) {
String var10000 = var1[var3];
}
List<String> list = new LinkedList();
String var7;
for(Iterator var6 = list.iterator(); var6.hasNext(); var7 = (String)var6.next()) {
;
}
可以看到foreach 在在处理数组和集合类时候会被编译成两种不同的形式。其中遍历集合时,是使用迭代器(iterator) ,这也解释了为什么foreach不能在循环内部移除成员。
2.泛型
java中泛型也是一种语法糖。又被叫做伪泛型,编译后Class文件类型就变成原生类型(类型擦除),而在引用处插入强制类型转换以实现JVM对泛型的支持。
demo:
List<String> list = new LinkedList<>();
list.add("a");
String a = list.get(0);
编译后:
List<String> list = new LinkedList();
list.add("a");
String a = (String)list.get(0);
3.switch-case语法支持枚举类和String类
这里就简单以String为例子,其实enum也是类似的,感兴趣的同学可以自己写个demo查看编译后的结果。
demo:
switch (animal) {
case "cat":
//doSomething
break;
case "dog":
//doSomething
break;
case "fish":
//doSomething
break;
default:
break;
}
编译后:
byte var3 = -1;
switch(animal.hashCode()) {
case 98262:
if (animal.equals("cat")) {
var3 = 0;
}
break;
case 99644:
if (animal.equals("dog")) {
var3 = 1;
}
break;
case 3143256:
if (animal.equals("fish")) {
var3 = 2;
}
}
switch(var3) {
case 0:
case 1:
case 2:
default:
}
在jdk7前,switch只支持short,char,int,byte(或者他们的包装类)和enum类型,在jdk7之后加入了String。编译之后,其实是通过String的hascode值来作为switch的值,再进行String的equal判断加强准确性(因为不同hashcode可能相同)。
try-with-resources
在Java中,如果打开了外部资源(文件、数据库连接、网络连接等),必须在这些外部资源使用完毕后手动关闭它们,否则导致外部资源泄露。在实际coding中我们常常会去些很多try-catch-finally的语句来确保自己关闭了这些资源。try-with-resources也是jdk7之后新加的语法,他旨在使之关闭资源的代码更优雅且可读。前提是资源类要实现java.lang.AutoCloseable或者java.io.Closable接口。
demo:
try (FileInputStream fin = new FileInputStream("C:\\test.log")) {
//doSomething
fin.read();
} catch (Exception e) {
e.printStackTrace();
}
编译后:
try {
FileInputStream fin = new FileInputStream("C:\\test.log");
Throwable var2 = null;
try {
fin.read();
} catch (Throwable var12) {
var2 = var12;
throw var12;
} finally {
if (fin != null) {
if (var2 != null) {
try {
fin.close();
} catch (Throwable var11) {
var2.addSuppressed(var11);
}
} else {
fin.close();
}
}
}
} catch (Exception var14) {
var14.printStackTrace();
}
编译后其实代码与传统方式的try-catch-finally十分相似,但是这种写法避免了手动去写close资源的代码,使代码更简洁。