通过字节码扒一扒java编译器瞒着我们做了什么(3)
来源:互联网 发布:java序列化 编辑:程序博客网 时间:2024/06/05 19:56
1. 数组和二维数组在字节码中的实现
源码:
int[] list1 = {1,2};
int[][] list2 = {{1,2},{3,4}};
字节码:
int[] list1;
descriptor: [I
flags:
int[][] list2;
descriptor: [[I
flags:
10: aload_0
11: iconst_2
12: newarray int
14: dup
15: iconst_0
16: iconst_1
17: iastore
18: dup
19: iconst_1
20: iconst_2
21: iastore
22: putfield #24 // Field list1:[I
25: aload_0
26: iconst_2
27: anewarray #26 // class "[I"
30: dup
31: iconst_0
32: iconst_2
33: newarray int
35: dup
36: iconst_0
37: iconst_1
38: iastore
39: dup
40: iconst_1
41: iconst_2
42: iastore
43: aastore
44: dup
45: iconst_1
46: iconst_2
47: newarray int
49: dup
50: iconst_0
51: iconst_3
52: iastore
53: dup
54: iconst_1
55: iconst_4
56: iastore
57: aastore
58: putfield #27 // Field list2:[[I
--红色部分是一维数组的初始化过程,注意命令newarray,可见在java中数组是分配到堆内存的对象,绿色部分是二维数组的初始化过程,注意27: anewarray #26 // class "[I"这行,意思是new 出一个存储引用类型的数组,而这个引用类型是类型[I,什么意思,这是int[]类型的签名,所以可见数组在java中不是基础类型而是个类类型。然后分别new两个一维数组并初始化后加入new出来的二维数组中。
2.数组和ArrayList的区别:
之前一直有个疑问,数组会不会也是颗语法糖,会不会编译器最终还是把数组转化成ArrayList类型,通过字节码可以发现,两者是不同类类型。
源码:
int[]list1 = {1,2};
List<String>list3 = new ArrayList<String>();
字节码:
int[] list1;
descriptor: [I
flags:
java.util.List<java.lang.String> list3;
descriptor: Ljava/util/List;
flags:
Signature: #16 // Ljava/util/List<Ljava/lang/String;>;
10: aload_0
11: iconst_2
12: newarray int
14: dup
15: iconst_0
16: iconst_1
17: iastore
18: dup
19: iconst_1
20: iconst_2
21: iastore
22: putfield #24 // Field list1:[I
61: aload_0
62: new #29 // class java/util/ArrayList
65: dup
66: invokespecial #31 // Methodjava/util/ArrayList."<in
it>":()V
--红色部分是一维数组的初始化指令,而绿色部分是ArrayList的初始化指令,显而易见,两者根本不是同种类类型,编译器并没有帮我们做转换。
3.可见性关键字volatile:
源码:
volatileint a = 99;
字节码:
volatile int a;
descriptor: I
flags: ACC_VOLATILE
4: aload_0
5: bipush 99
7: putfield #24 // Field a:I
--可见,对于volatile定义的成员,字节码中成员声明和正常的int 成员是不同的,但是初始化过程跟正常int成员一模一样,说明,可见性是由JVM来保障的,并非由代码保障的。估计是JVM遇到volatile变量就会禁止各个线程的寄存器拷贝该变量以此保障volatile变量在多线程中的可见性。
4.null对象是什么?
源码:
Arraylist4 = null;
字节码:
72: aload_0
73: aconst_null
74: putfield #36 // Field list4:Ljava/lang/reflect/
rray;
--可见null在字节码中就是null。
- 通过字节码扒一扒java编译器瞒着我们做了什么(3)
- 通过字节码扒一扒java编译器瞒着我们做了什么(1)
- 通过字节码扒一扒java编译器瞒着我们做了什么(2)
- 你知道编译器为我们做了些什么吗?
- 当我们点击了编译时,编译器都为我们做了什么
- 《深度探索C++对象模型》读书笔记4:构造语意学,编译器背着我们做了什么?
- IPC之AIDL(3)系统为我们做了什么
- 十年来,我们做了什么?
- 了解new为我们做了什么
- Startup Upgrade为我们做了什么?
- jQuery 替我们做了什么
- Struts2到底为我们做了什么
- 我们通过Kotlin得到了什么?
- 当我们老了,什么都来不及做了!
- 我们在一起八年,他竟瞒着我做这样的事情
- C++编译器默默为你做了些什么?
- C++编译器创建的默认构造究竟做了什么??
- 理解编译器在编译过程中做了什么
- “Or" Game CodeForces
- redis学习笔记
- c# swagger 笔记一
- Android Studio NDK CMake 指定so输出路径以及生成多个so的案例与总结
- POJ1511 Invitation Cards
- 通过字节码扒一扒java编译器瞒着我们做了什么(3)
- scala 元组tuple的几个知识点
- Mysql触发器
- Apache 服务器无法正常工作问题
- 【Away3D代码解读】(三):渲染核心流程(渲染)
- Java设计模式简介
- HUSTOJ随笔3-配置文件
- 基于HtmlUnit获取页面及复选框元素、单击事件操作
- C语言中的数据类型和隐式转换