java 语法糖中的坑
语法糖
java中的语法糖
- switch 支持 String 与枚举(Java 7开始支持String,String的本质还是数值)
- 泛型(jvm在编译阶段采用类型擦除的方式解糖)
- 自动拆装箱
- 可变长参数(一个方法中只能有一个可变长参数,如果有其他参数,可变长参数必须放在最后)
- 枚举
- 内部类
- 条件编译
- 断言
- 数值字面量(支持整数和浮点数,只是为了方便阅读)
- for-each(只是简化书写,本质还是用for循环和迭代器实现)
- try-with-resource(优化try-catch-finally结构)
- lambda(简化函数式接口书写)
语法糖中的坑点
泛型
一、当泛型遇到重载 public class GenericTypes {
public static void method(List<String> list) {
System.out.println("invoke method(List<String> list)");
}
public static void method(List<Integer> list) {
System.out.println("invoke method(List<Integer> list)");
}
}
上面这段代码,有两个重载的函数,因为他们的参数类型不同,一个是List
二、当泛型遇到catch 泛型的类型参数不能用在Java异常处理的catch语句中。因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,JVM是无法区分两个异常类型MyException<String>
和MyException<Integer>
的
三、当泛型内包含静态变量
public class StaticTest{
public static void main(String[] args){
GT<Integer> gti = new GT<Integer>();
gti.var=1;
GT<String> gts = new GT<String>();
gts.var=2;
System.out.println(gti.var);
}
}
class GT<T>{
public static int var=0;
public void nothing(T x){}
}
以上代码输出结果为:2!由于经过类型擦除,所有的泛型类实例都关联到同一份字节码上,泛型类的所有静态变量是共享的。
自动装箱与拆箱
对象相等比较
public class BoxingTest {
public static void main(String[] args) {
Integer a = 1000;
Integer b = 1000;
Integer c = 100;
Integer d = 100;
System.out.println("a == b is " + (a == b));
System.out.println(("c == d is " + (c == d)));
}
}
输出结果:
a == b is false
c == d is true
在Java 5中,在Integer的操作上引入了一个新功能来节省内存和提高性能。整型对象通过使用相同的对象引用实现了缓存和重用。
转载补充:阿里开发手册中有讲到Integer包装类的这个坑!!!
.
适用于整数值区间-128 至 +127。
只适用于自动装箱。使用构造函数创建对象不适用。
增强for循环
ConcurrentModificationException
for (Student stu : students) {
if (stu.getId() == 2)
students.remove(stu);
}
会抛出ConcurrentModificationException
异常。
Iterator是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出java.util.ConcurrentModificationException
异常。
所以 Iterator
在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator
本身的方法remove()
来删除对象,Iterator.remove()
方法会在删除当前迭代对象的同时维护索引的一致性。
总结
前面介绍了12种Java中常用的语法糖。所谓语法糖就是提供给开发人员便于开发的一种语法而已。但是这种语法只有开发人员认识。要想被执行,需要进行解糖,即转成JVM认识的语法。当我们把语法糖解糖之后,你就会发现其实我们日常使用的这些方便的语法,其实都是一些其他更简单的语法构成的。
有了这些语法糖,我们在日常开发的时候可以大大提升效率,但是同时也要避免过渡使用。使用之前最好了解下原理,避免掉坑。
原文参考
贴上引用地址,如需自取:https://developer.aliyun.com/article/702384?spm=a2c6h.12873639.0.0.49cc54aa3ayibH