04JVM_语法糖

一、编译期处理

语法糖java编译器把*.java源码编译为*.class字节码的过程中,自动生成和转换的一些代码(添加的class字节码),减轻程序员的负担。

1.默认构造器

默认构造器没有写任何的构造方法,但经过编译器编译成字节码过程中,会加上调用父类Object的无参构造方法。调用java/lang/Object.””()V

04JVM_语法糖_第1张图片

2.自动拆装箱

①在JDK 5之前,基本类型int转换成包装类型Integer需要手动装箱

Integer x = Integer.valueOf(2);

包装类型Integer转换为基本类型int需要手动拆箱

int y = x.intValue();

②在JDK 5 之后,由编译器在编译阶段实现自动拆装箱

04JVM_语法糖_第2张图片

补充:

Integer在-128~127会复用对象。地址相同

3.泛型集合取值

1.泛型擦除

JDK5后,java在编译泛型代码后执行泛型擦除的动作,泛型信息都当作Object类型处理。

取值的时候会进行Object强制类型转换。

04JVM_语法糖_第3张图片

 

①当调用list.add(10)时,实际调用的是list.add(Object e)这个方法。把泛型信息当成Object处理

②当调用 Integer x = list.get(0),实际调用Object obj = list.get(int index)方法。最后Object类型转换为Integer。Integer x = (Integer)list.get(0)

③如果调用 int x = list.get(0)。类型转换是int x = ((Integer)list.get(0)).intValue();

2.泛型反射

局部变量类型表LocalVariableTable:方法内参数的泛型信息

04JVM_语法糖_第4张图片

只有方法参数方法返回值,带的泛型信息才能反射获取到。

 04JVM_语法糖_第5张图片

4.可变参数

04JVM_语法糖_第6张图片

可变参数是JDK 5加入的特性,String... args其实是String []

调用foo(实参1,实参2)方法,编译器会根据实参的数量生成一个String数组new String[]{”hello”,”world”}

04JVM_语法糖_第7张图片

注意:

如果调用foo()无参方法,那么创建一个空的数组new String[]{},而不是传递null

4.foreach循环

数组循环,JDK 5 加入语法糖,按照下标区遍历的循环结构

04JVM_语法糖_第8张图片

①int[] array = {1, 2, 3, 4, 5};编译器转换

int[] array = new int[] {1, 2, 3, 4, 5};

②int e: array 编译器会转换为按照下标区遍历的循环结构。

04JVM_语法糖_第9张图片

集合循环

foreach循环被编译器转换为迭代器的调用 list.iterator()

04JVM_语法糖_第10张图片

注意:

foreach循环,配合数组和实现了Iterator()接口的集合类一起使用。

5.switch字符串

JDK7开始switch可以用字符串枚举类

04JVM_语法糖_第11张图片

switch配合字符串枚举类,变量不为null.编译后的字节码文件如下。

第一遍是根据字符串的hashCode和equals将字符串转换为byte类,第二遍根据byte进行比较。

04JVM_语法糖_第12张图片

 

 6.switch枚举

原始代码

 04JVM_语法糖_第13张图片

 

转换后代码

①定义一个合成类,用来映射枚举的ordinal与数组关系

②枚举的ordinal表示枚举对象的序号,从0开始

③MALE的ordinal()=0,FEMALE的ordinal()=1

04JVM_语法糖_第14张图片

 

7.枚举类

JDK 7 新增

枚举类本质是class,枚举值是class的一个对象。

04JVM_语法糖_第15张图片

 转换后

04JVM_语法糖_第16张图片

 8.try-with-resources关闭资源处理

04JVM_语法糖_第17张图片

①JDK 7 开始,只要资源对象实现了AutoCloseable接口(文件输入输出流),使用try-with-resources不用写finally语句。编译器在finally会新增正常结束或者抛出异常的方法。

②设计一个addSuppressed(Throwable e)添加被压制异常的方法呢?

为了防止异常信息的丢失。

9.方法重写时的桥接方法

方法重写时返回值有2种情况

①子类的返回值跟父类一致

②子类的返回值是父类返回值的子类

04JVM_语法糖_第18张图片

对于子类的返回值是父类返回值的子类。编译器会自动生成一个重写父类的方法,采用桥接的方式

public synthetic bridge Number m()调用子类的方法,同时符合重写的规则。

10.匿名内部类

源代码 

04JVM_语法糖_第19张图片

转换后的代码

①生成一个额外的类Candy11$1实现Runnable接口。

04JVM_语法糖_第20张图片

 ②创建匿名内部类Candy11$1的对象

04JVM_语法糖_第21张图片

注意:

匿名内部类引用局部变量时,局部变量必须是final不可变的。因为编译器在创建匿名对象时,将复制给匿名对象的value属性,x就不能发生变化了,值固定住了。

你可能感兴趣的:(JVM,java,jvm)