前言
一、默认构造函数
- 1.案例代码
- 2.编译优化后
二、自动拆装箱
- 1.案例代码
- 2.编译优化后
二、泛型集合取值
- 1.案例代码
- 2.字节码文件
前言
语法糖:其实就是指java编译器把 .java 源文件编译为 .class 字节码的过程,自动生成和转换的代码,主要是为了减轻程序员的负担,算是java编译器给我们的额外福利。
注意,以下代码的分析,借助了javap工具,idea的反编译功能,idea插件jclasslib等工具,编译器转换的结果就是class字节码,只是为了便于阅读,给出几乎等价的Java源码方式,并不是编译器还会转换出中间的Java源码。
提示:以下是本篇文章正文内容,下面案例可供参考
一、默认构造函数
1.案例代码
代码如下:
public class Candy1 {
}
2.编译优化后
代码如下:
public class Candy1 {
//这个无参构造器是java编译器帮我们加上的
public Candy1() {
//即调用父类 Object 的无参构造方法,即调用 java/lang/Object." <init>":()V
super();
}
}
原始代码在经过编译优化后会添加一个无参构造,这就是默认构造方法。
在默认构造方法中会调用父类的无参构造。
二、自动拆装箱
基本类型和其他包装类型的相互转换过程,称为拆装箱。
在JDK5以后,它们的转换都可以在编译器自动完成。
1.案例代码
代码如下:
public class Demo2 {
public static void main(String[] args) {
Integer x = 1;
int y = x;
}
}
2.编译优化后
代码如下:
public class Demo2 {
public static void main(String[] args) {
//基本类型赋值给包装类型,称为装箱
Integer x = Integer.valueOf(1);
//包装类型赋值给基本类型,称谓拆箱
int y = x.intValue();
}
}
在代码经过编译优化后,可以发现会通过添加一些固定的代码,减少程序员负担。
在拆箱和装箱过程中,因为代码都是固定不变,所以可以进行优化。
二、泛型集合取值
泛型也是在JDK 5 开始加入的特性,但Java在编译泛型代码后会执行泛型擦除,即泛型信息在编译为字节码之后就丢失了,实际的类型都当作了Object类型来处理。
1.案例代码
代码如下:
public class Demo3 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(10);
Integer x = list.get(0);
}
}
2.字节码文件
字节码如下:
Code:
stack=2, locals=3, args_size=1
0: new #2 // class java/util/ArrayList
3: dup
4: invokespecial #3 // Method java/util/ArrayList."<init>":()V
7: astore_1
8: aload_1
9: bipush 10
11: invokestatic #4 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
//这里进行了泛型擦除,实际调用的是add(Objcet o)
14: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
19: pop
20: aload_1
21: iconst_0
//这里也进行了泛型擦除,实际调用的是get(Object o)
22: invokeinterface #6, 2 // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
//这里进行了类型转换,将Object转换成了Integer
27: checkcast #7 // class java/lang/Integer
30: astore_2
31: return
在上图字节码文件中,我们可以重点关注14以及27行指令,分别对应擦除,以及转换。
14行指令这里进行了泛型擦除,实际调用的是add(Objcet o)。
//这里进行了泛型擦除,实际调用的是add(Objcet o)
14: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
27行指令这里进行了类型转换,将Object转换成了Integer
//这里进行了类型转换,将Object转换成了Integer
27: checkcast #7 // class java/lang/Integer
在调用get函数取值时,有一个类型转换的操作:
Integer x = (Integer) list.get(0);
如果要将返回结果赋值给一个int类型的变量,则还有自动拆箱的操作:
int x = (Integer) list.get(0).intValue();