Class文件实例解析
来源:互联网 发布:淘宝卡西欧海神 编辑:程序博客网 时间:2024/06/06 13:59
http://www.cnblogs.com/focusj/archive/2012/03/05/2375357.html
前面发了几篇学习笔记,但是看这些东西总是感觉很"玄乎",来一篇实战的东西来揭一下"JVM"的面纱,让"SSH"时代的童鞋们来熟悉一下Java的"老祖爷"JVM。由于自己的水平有限,所以大家在看过程中发了什么问题,或者您有什么疑问请及时提出来,我及时解决。如果您有什么建议,那么更好大家一块讨论。
1. 源码文件
public
class
LearningClassFile {
//普通变量
private
int
id1;
//静态变量
private
static
int
id2;
//常量
private
final
int
id3 =
4
;
//静态常量
private
static
final
int
id4 =
5
;
public
LearningClassFile() {
}
public
LearningClassFile(
int
id1,
int
id2) {
this
.id1 = id1;
this
.id2 = id2;
}
//使用public修饰的addPub方法
public
void
addPub(
int
a,
int
b) {
int
result = a + b;
System.out.println(result);
}
//使用private修饰的addPri方法
private
void
addPri(
int
a,
int
b) {
int
result = a + b;
System.out.println(result);
}
//使用static修饰的方法
public
static
void
addSta() {
int
result = id2 + id4;
System.out.println(result);
}
public
static
final
void
addFinal(
int
a,
int
b) {
int
result = a + b;
System.out.println(result);
}
public
static
void
main(String[] args) {
LearningClassFile lcf =
new
LearningClassFile(
1
,
2
);
lcf.addPub(
1
,
2
);
lcf.addPri(
1
,
2
);
addSta();
addFinal(
1
,
2
);
}
}
Class文件:
Compiled from
"LearningClassFile.java"
public
class
LearningClassFile
extends
java.lang.Object
SourceFile:
"LearningClassFile.java"
minor version:
0
major version:
50
//运行时常量池:用于存放编译期生成的各种字面量和符号引用。
Constant pool:
//从父类Object继承的默认构造方法
//观察该方法的特征:无参,返回类型void
const
#
1
= Method #
13
.#
35
;
// java/lang/Object."<init>":()V
//常量id3
//"#7.#36; // LearningClassFile.id3:I"
//#7:查找常量池中的类名LearningClassFile
//#36-->"const #36 = NameAndType #17:#15;// id3:I"
//NameAndType字面的意思是名称和类型。即id3是变量的名称,I表示id3是int类型
//综合描述:LearningClassFile中的id3是int类型
const
#
2
= Field #
7
.#
36
;
// LearningClassFile.id3:I
const
#
3
= Field #
7
.#
37
;
// LearningClassFile.id1:I
const
#
4
= Field #
7
.#
38
;
// LearningClassFile.id2:I
//将System的out存储至常量池
//System类中out被public static final修饰的
//"public final static PrintStream out = nullPrintStream();"
//综合描述:System类的out属性是PrintStream类型
const
#
5
= Field #
39
.#
40
;
// java/lang/System.out:Ljava/io/PrintS
tream;
//将PrintStream的Println()方法存储至常量池
//该方法的参数为I,返回值为void
const
#
6
= Method #
41
.#
42
;
// java/io/PrintStream.println:(I)V
//类LearningClassFIle
const
#
7
=
class
#
43
;
// LearningClassFile
//构造函数
//该构造函数需传入两个int类型的变量
const
#
8
= Method #
7
.#
44
;
// LearningClassFile."<init>":(II)V
//LearningClassFile的addPub方法
//#4-->"const #45 = NameAndType #27:#26;// addPub:(II)V"
//#27-->"const #27 = Asciz addPub;" 方法的名称为:addPub
//#26-->"const #26 = Asciz (II)V;" 方法的类型:两个int类型的参数,返回类型为void
const
#
9
= Method #
7
.#
45
;
// LearningClassFile.addPub:(II)V
const
#
10
= Method #
7
.#
46
;
// LearningClassFile.addPri:(II)V
const
#
11
= Method #
7
.#
47
;
// LearningClassFile.addSta:()V
const
#
12
= Method #
7
.#
48
;
// LearningClassFile.addFinal:(II)V
const
#
13
=
class
#
49
;
// java/lang/Object
const
#
14
= Asciz id1;
const
#
15
= Asciz I;
const
#
16
= Asciz id2;
const
#
17
= Asciz id3;
//ConstantValue属性表示一个常量字段的值
//即final修饰的属性
const
#
18
= Asciz ConstantValue;
//对于final修饰的常量直接将类型和值存入常量池
const
#
19
=
int
4
;
const
#
20
= Asciz id4;
const
#
21
=
int
5
;
const
#
22
= Asciz <init>;
const
#
23
= Asciz ()V;
//Code属性只为唯一一个方法、实例类初始化方法或类初始化方法保存Java虚拟机指令及相关辅助信息
//简而言之:保存方法编译后的指令信息
const
#
24
= Asciz Code;
//java源码行号与编译后的字节码指令的对应表
const
#
25
= Asciz LineNumberTable;
const
#
26
= Asciz (II)V;
const
#
27
= Asciz addPub;
const
#
28
= Asciz addPri;
const
#
29
= Asciz addSta;
const
#
30
= Asciz addFinal;
const
#
31
= Asciz main;
const
#
32
= Asciz ([Ljava/lang/String;)V;
//java 源码文件
const
#
33
= Asciz SourceFile;
const
#
34
= Asciz LearningClassFile.java;
const
#
35
= NameAndType #
22
:#
23
;
// "<init>":()V
const
#
36
= NameAndType #
17
:#
15
;
// id3:I
const
#
37
= NameAndType #
14
:#
15
;
// id1:I
const
#
38
= NameAndType #
16
:#
15
;
// id2:I
const
#
39
=
class
#
50
;
// java/lang/System
const
#
40
= NameAndType #
51
:#
52
;
// out:Ljava/io/PrintStream;
const
#
41
=
class
#
53
;
// java/io/PrintStream
const
#
42
= NameAndType #
54
:#
55
;
// println:(I)V
const
#
43
= Asciz LearningClassFile;
const
#
44
= NameAndType #
22
:#
26
;
// "<init>":(II)V
const
#
45
= NameAndType #
27
:#
26
;
// addPub:(II)V
const
#
46
= NameAndType #
28
:#
26
;
// addPri:(II)V
const
#
47
= NameAndType #
29
:#
23
;
// addSta:()V
const
#
48
= NameAndType #
30
:#
26
;
// addFinal:(II)V
const
#
49
= Asciz java/lang/Object;
const
#
50
= Asciz java/lang/System;
const
#
51
= Asciz out;
const
#
52
= Asciz Ljava/io/PrintStream;;
const
#
53
= Asciz java/io/PrintStream;
const
#
54
= Asciz println;
const
#
55
= Asciz (I)V;
{
//默认构造方法
public
LearningClassFile();
Code:
Stack=
2
, Locals=
1
, Args_size=
1
0
: aload_0
1
: invokespecial #
1
;
//Method java/lang/Object."<init>":()V
//将id3的引用推送至栈顶
4
: aload_0
//将4推送至栈顶
5
: iconst_4
//将4赋值给id3
6
: putfield #
2
;
//Field id3:I
9
:
return
LineNumberTable:
line
11
:
0
//public LearningClassFile() {
//对于final类型的实例变量在每个构造方法中都会进行一次初始化。
line
7
:
4
// private final int id3 = 4;
line
12
:
9
//}
public
LearningClassFile(
int
,
int
);
Code:
Stack=
2
, Locals=
3
, Args_size=
3
0
: aload_0
1
: invokespecial #
1
;
//Method java/lang/Object."<init>":()V
4
: aload_0
5
: iconst_4
6
: putfield #
2
;
//Field id3:I
9
: aload_0
10
: iload_1
11
: putfield #
3
;
//Field id1:I
14
: aload_0
15
: pop
16
: iload_2
17
: putstatic #
4
;
//Field id2:I
20
:
return
LineNumberTable:
line
14
:
0
//public LearningClassFile(int id1, int id2) {
//对于final类型的实例变量在每个构造方法中都会进行一次初始化。
line
7
:
4
// private final int id3 = 4;
line
15
:
9
// this.id1 = id1;
line
16
:
14
// this.id2 = id2;
line
17
:
20
//}
public
void
addPub(
int
,
int
);
Code:
Stack=
2
, Locals=
4
, Args_size=
3
0
: iload_1
1
: iload_2
2
: iadd
3
: istore_3
4
: getstatic #
5
;
//Field java/lang/System.out:Ljava/io/PrintStream;
7
: iload_3
8
: invokevirtual #
6
;
//Method java/io/PrintStream.println:(I)V
11
:
return
LineNumberTable:
line
21
:
0
// int result = a + b;
line
22
:
4
// System.out.println(result);
line
23
:
11
// }
public
static
void
addSta();
Code:
Stack=
2
, Locals=
1
, Args_size=
0
//获取静态变量id2推送至栈顶
0
: getstatic #
4
;
//Field id2:I
//直接从常量池中取出id4的值5推送至栈顶
3
: iconst_5
//执行相加操作
4
: iadd
//将计算结果推送至栈顶
5
: istore_0
//获取静态与out
6
: getstatic #
5
;
//Field java/lang/System.out:Ljava/io/PrintStream;
//取出计算结果
9
: iload_0
//调用println方法
10
: invokevirtual #
6
;
//Method java/io/PrintStream.println:(I)V
//方法正常结束
13
:
return
LineNumberTable:
line
33
:
0
// int result = id2 + id4;
line
34
:
6
// System.out.println(result);
line
35
:
13
//}
public
static
final
void
addFinal(
int
,
int
);
Code:
Stack=
2
, Locals=
3
, Args_size=
2
0
: iload_0
1
: iload_1
2
: iadd
3
: istore_2
4
: getstatic #
5
;
//Field java/lang/System.out:Ljava/io/PrintStream;
7
: iload_2
8
: invokevirtual #
6
;
//Method java/io/PrintStream.println:(I)V
11
:
return
LineNumberTable:
line
38
:
0
line
39
:
4
line
40
:
11
public
static
void
main(java.lang.String[]);
Code:
Stack=
4
, Locals=
2
, Args_size=
1
//创建一个LearningClassFile对象,并将对象的引用推送至栈顶
0
:
new
#
7
;
//class LearningClassFile
//将对象的引用进行备份推送至栈顶
//使用原有的引用值调用实例方法,现在置于栈顶的引用值的位置将被接下来的操作覆盖。
3
: dup
//将构造函数中的参数1推送至栈顶
4
: iconst_1
5
: iconst_2
//执行构造方法
6
: invokespecial #
8
;
//Method "<init>":(II)V
//将栈顶引用型数值存入第二个本地变量
9
: astore_1
10
: aload_1
11
: iconst_1
12
: iconst_2
//调用实例方法
13
: invokevirtual #
9
;
//Method addPub:(II)V
16
: aload_1
17
: iconst_1
18
: iconst_2
19
: invokespecial #
10
;
//Method addPri:(II)V
//调用静态方法
22
: invokestatic #
11
;
//Method addSta:()V
25
: iconst_1
26
: iconst_2
27
: invokestatic #
12
;
//Method addFinal:(II)V
30
:
return
LineNumberTable:
line
43
:
0
// LearningClassFile lcf = new LearningClassFile(1, 2);
line
44
:
10
// lcf.addPub(1, 2);
line
45
:
16
// lcf.addPri(1, 2);
line
46
:
22
// addSta();
line
47
:
25
// addFinal(1, 2);
line
48
:
30
//}
}
final
变量和
static
final
变量的区别:
1
. 实例常量和类常量的区别
2
. 初识方式不同:从
class
字节码来看
final
修饰的变量会出现在每个构造方法中进行一次初始化;
static
final
类型的变量必须在定义的时候进行初始化。
理解
"编译期可知,运行期不变"
: 编译器可确定调用方法的版本,符合这个标准的方法主要有两种:私有方法,静态方法。详情请看:深入理解JVM读书笔记--字节码执行引擎。
2. final变量和static final变量的区别: (1) 实例常量和类常量的区别 (2) 初始化方式不同:从class字节码来看final修饰的变量会出现在每个构造方法中进行一次初始化;static final类型的变量必须在定义的时候进行初始化。
3. 理解"编译期可知,运行期不变": 编译器可确定调用方法的版本,符合这个标准的方法主要有两种:私有方法,静态方法。详情请看:深入理解JVM读书笔记--字节码执行引擎。
- Class文件实例解析
- Java Class文件解析实例
- java的class文件解析实例
- 深入java虚拟机--Class文件实例解析
- 深入Java虚拟机:Class文件实例解析
- 二进制 java Class文件解析实例
- Java Class文件结构解析 及 实例分析验证
- Class文件实例
- Java Class 文件解析
- eclipse .class 文件解析
- 解析class反编译文件
- java class文件解析
- 解析class文件-方法
- class文件解析
- JAVA CLASS 文件解析
- 实例解析Java class文件格式
- 解析java的*.class文件
- 解析class文件常量池
- no debugging symbols found
- 网页设计的流行趋势
- PL/SQL Developer工具登陆一个新创建的用户进行查询时报Dynamic Performance Tables not accessible
- jquery 常用的那些标签
- 伤别
- Class文件实例解析
- JAVA考试知识覆盖要点
- 错误契约FaultContract
- atol(atoi)函数的实现要点
- 一生何求
- SQL-Server重置自标识列 应用
- DetachedCriteria 用法
- Torvalds' quote about good programmer
- ffmpeg 解码h264