finsh 常量池及相关内容

master
Omooo 6 years ago
parent dcee031458
commit c25a0c1000
  1. 12
      README.md
  2. 29
      blogs/JVM/深入理解 Class 文件格式/属性介绍.md
  3. 104
      blogs/JVM/深入理解 Class 文件格式/常量池及相关内容.md

@ -54,7 +54,13 @@ Android Notes
##### JVM、ART 相关 ##### JVM、ART 相关
[Class 文件格式总览](https://github.com/Omooo/Android-Notes/blob/master/blogs/JVM/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%20Class%20%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F/Class%20%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%E6%80%BB%E8%A7%88.md) Class 文件格式
[Class 文件格式总览](https://github.com/Omooo/Android-Notes/blob/master/blogs/JVM/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%20Class%20%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F/Class%20%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F%E6%80%BB%E8%A7%88.md)
[常量池及相关内容](https://github.com/Omooo/Android-Notes/blob/master/blogs/JVM/深入理解 Class 文件格式/常量池及相关内容.md)
[属性介绍]
##### 性能优化 ##### 性能优化
@ -80,7 +86,9 @@ Android Notes
#### Framework #### Framework
[Android 系统架构]() [Android 系统架构](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/Framework/Android 系统架构.md)
[Android 系统启动](https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/Framework/Android 系统启动.md)
#### Java 基础 #### Java 基础

@ -0,0 +1,29 @@
---
属性介绍
---
#### 目录
1. 属性概述
2. Code 属性
3. LineNumberTable 属性
4. LocalVariableTable 属性
#### 属性概述
属性是 Class 文件的重要组成部分。和常量池类似,属性也分为很多类型,在 Java 虚拟机规范中,属性可用 attribute_info 数据结构伪代码表示:
```
attribute_info{
//属性名称,指向常量池中 Utf8 常量项的索引
u2 attribute_name_index;
//该属性具体内容的长度,即下面 info 数组的长度
u4 attribute_length;
//属性具体内容
u1 info[attribute_length];
}
```

@ -6,6 +6,8 @@
1. 常量项的类型和关系 1. 常量项的类型和关系
2. 信息描述规则 2. 信息描述规则
3. field_info 和 method_info
4. access_flags 介绍
#### 常量项的类型和关系 #### 常量项的类型和关系
@ -134,4 +136,104 @@ CONSTANT_Float_info{
#### 信息描述规则 #### 信息描述规则
根据 Java 虚拟机规范,如何用字符串来描述成员变量、成员函数是有讲究的, 根据 Java 虚拟机规范,如何用字符串来描述成员变量、成员函数是有讲究的,这些规则主要集中在数据类型、成员变量和成员函数的描述规则。包括
- 数据类型的描述规则
- 成员变量的描述规则,即 Field Descriptor
- 成员函数的描述规则,即 Method Descriptor
##### 数据类型的描述规则
| 类型 | 描述 |
| ------- | ------------------ |
| byte | B |
| char | C |
| double | D |
| float | F |
| int | I |
| long | J |
| short | S |
| boolean | B |
| String | Ljava/lang/String; |
| int[] | [I |
##### 成员变量描述规则
就是类似上面的数据类型。
##### 成员函数描述规则
和成员变量略有不同的是,一个成员函数(Method Description)的描述需要包含返回值及参数的数据类型。
比如,对于 System.out.print(String str) 函数,它的 Method Description 是:
```java
(Ljava/lang/String;)V
```
Method Description 不包含函数名,这样做的目的其实也是为了节省空间,因为很多函数可能名字不同,但是它们的 Method Description 是一样的。
#### field_info 和 method_info
它们的数据结构伪代码如下:
```java
field_info{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
method_info{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
```
- access_flags
访问标志
- name_index
指向成员变量或成员函数的名字的 Utf8_info 常量项。
- descriptor_index
也指向 Utf8_info 常量项,其内容分别是描述成员变量的 FieldDescriptor 和描述成员函数的 MethodDescriptor。
- attributes
为属性信息,成员域和成员函数都包含若干属性。
既然 method_info 描述的是一个成员函数,那么这个函数对应的代码经过编译后得到的 Java 字节码存储在什么地方呢?
其实存储在属性中。
#### access_flags
access_flags 其实就是访问修饰符,如下:
| 标识位 | 说明 |
| ---------------- | -------------------- |
| ACC_PUBLIC | public |
| ACC_FINAL | final |
| ACC_INTERFACE | interface |
| ACC_ABSTRACT | abstract |
| ACC_ANNOTATION | annotation |
| ACC_ENUM | 枚举类型 |
| ACC_PROTECT | protect |
| ACC_STATIC | static |
| ACC_VOLATILE | volatile |
| ACC_TRANSIENT | transient |
| ACC_NATIVE | native |
| ACC_VARARGS | 可变长参数个数的函数 |
| ACC_SYNCHRONIZED | synchronized |
| ... | ... |
之前写过,关于 synchronized 方法的实现原理,是在方法前面加上 ACC_SYNCHRONIZED 的标识位,原本我以为只有 synchronized 方法会有这种标识位,其他一些访问修饰符都没有,看来还是 too young too simple~
Loading…
Cancel
Save