前言
从字节码看java中 this 隐式传参具体体现(和python中的self如出一辙,但是比python中藏得更深),也发现了 static 与 非 static 方法的区别所在!
static与非static方法都是存储java的方法区。在static 方法中,没有this引用,因此无法使用当前类中所定义的变量,而非static方法则会默认传入this。
概述
我们今天就从另一个角度来真实看一下这个答案吧!
来个例子,并将其反编译为可视代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class hello {
private final int ii;
public hello(int a) {
ii = a;
}
public static void main(string[] args) throws exception {
sayhellostatic("ok");
}
public void sayhello(string word) {
system.out.println("hello, " + word);
}
public static void sayhellostatic(string word) {
system.out.println("static hello, " + word);
}
}
|
反汇编命令:
|
1
|
javap -verbose hello.class
|
反汇编结果:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
classfile /d:/xx/target/classes/com/xx/api/hello.class
last modified 2018-11-8; size 1069 bytes
md5 checksum 9d39cd9d4e95588a73c059a4e69f01e8
compiled from "hello.java"
public class com.xx.api.hello
minor version: 0
major version: 52
flags: acc_public, acc_super
constant pool:
#1 = methodref #14.#38 // java/lang/object."<init>":()v
#2 = fieldref #13.#39 // com/xx/api/hello.ii:i
#3 = string #40 // ok
#4 = methodref #13.#41 // com/xx/api/hello.sayhellostatic:(ljava/lang/string;)v
#5 = fieldref #42.#43 // java/lang/system.out:ljava/io/printstream;
#6 = class #44 // java/lang/stringbuilder
#7 = methodref #6.#38 // java/lang/stringbuilder."<init>":()v
#8 = string #45 // hello,
#9 = methodref #6.#46 // java/lang/stringbuilder.append:(ljava/lang/string;)ljava/lang/stringbuilder;
#10 = methodref #6.#47 // java/lang/stringbuilder.tostring:()ljava/lang/string;
#11 = methodref #48.#49 // java/io/printstream.println:(ljava/lang/string;)v
#12 = string #50 // static hello,
#13 = class #51 // com/xx/api/hello
#14 = class #52 // java/lang/object
#15 = utf8 ii
#16 = utf8 i
#17 = utf8 <init>
#18 = utf8 (i)v
#19 = utf8 code
#20 = utf8 linenumbertable
#21 = utf8 localvariabletable
#22 = utf8 this
#23 = utf8 lcom/xx/api/hello;
#24 = utf8 a
#25 = utf8 main
#26 = utf8 ([ljava/lang/string;)v
#27 = utf8 args
#28 = utf8 [ljava/lang/string;
#29 = utf8 exceptions
#30 = class #53 // java/lang/exception
#31 = utf8 sayhello
#32 = utf8 (ljava/lang/string;)v
#33 = utf8 word
#34 = utf8 ljava/lang/string;
#35 = utf8 sayhellostatic
#36 = utf8 sourcefile
#37 = utf8 hello.java
#38 = nameandtype #17:#54 // "<init>":()v
#39 = nameandtype #15:#16 // ii:i
#40 = utf8 ok
#41 = nameandtype #35:#32 // sayhellostatic:(ljava/lang/string;)v
#42 = class #55 // java/lang/system
#43 = nameandtype #56:#57 // out:ljava/io/printstream;
#44 = utf8 java/lang/stringbuilder
#45 = utf8 hello,
#46 = nameandtype #58:#59 // append:(ljava/lang/string;)ljava/lang/stringbuilder;
#47 = nameandtype #60:#61 // tostring:()ljava/lang/string;
#48 = class #62 // java/io/printstream
#49 = nameandtype #63:#32 // println:(ljava/lang/string;)v
#50 = utf8 static hello,
#51 = utf8 com/xx/api/hello
#52 = utf8 java/lang/object
#53 = utf8 java/lang/exception
#54 = utf8 ()v
#55 = utf8 java/lang/system
#56 = utf8 out
#57 = utf8 ljava/io/printstream;
#58 = utf8 append
#59 = utf8 (ljava/lang/string;)ljava/lang/stringbuilder;
#60 = utf8 tostring
#61 = utf8 ()ljava/lang/string;
#62 = utf8 java/io/printstream
#63 = utf8 println
{
public com.xx.api.hello(int);
descriptor: (i)v
flags: acc_public
code:
stack=2, locals=2, args_size=2
0: aload_0
1: invokespecial #1 // method java/lang/object."<init>":()v
4: aload_0
5: iload_1
6: putfield #2 // field ii:i
9: return
linenumbertable:
line 14: 0
line 15: 4
line 16: 9
localvariabletable:
start length slot name signature
10 0 this lcom/xx/api/hello;
10 1 a i
public static void main(java.lang.string[]) throws java.lang.exception;
descriptor: ([ljava/lang/string;)v
flags: acc_public, acc_static
code:
stack=1, locals=1, args_size=1
0: ldc #3 // string ok
2: invokestatic #4 // method sayhellostatic:(ljava/lang/string;)v
5: return
linenumbertable:
line 42: 0
line 45: 5
localvariabletable:
start length slot name signature
6 0 args [ljava/lang/string;
exceptions:
throws java.lang.exception
public void sayhello(java.lang.string);
descriptor: (ljava/lang/string;)v
flags: acc_public
code:
stack=3, locals=2, args_size=2
0: getstatic #5 // field java/lang/system.out:ljava/io/printstream;
3: new #6 // class java/lang/stringbuilder
6: dup
7: invokespecial #7 // method java/lang/stringbuilder."<init>":()v
10: ldc #8 // string hello,
12: invokevirtual #9 // method java/lang/stringbuilder.append:(ljava/lang/string;)ljava/lang/stringbuilder;
15: aload_1
16: invokevirtual #9 // method java/lang/stringbuilder.append:(ljava/lang/string;)ljava/lang/stringbuilder;
19: invokevirtual #10 // method java/lang/stringbuilder.tostring:()ljava/lang/string;
22: invokevirtual #11 // method java/io/printstream.println:(ljava/lang/string;)v
25: return
linenumbertable:
line 48: 0
line 49: 25
localvariabletable:
start length slot name signature
26 0 this lcom/xx/api/hello;
26 1 word ljava/lang/string;
public static void sayhellostatic(java.lang.string);
descriptor: (ljava/lang/string;)v
flags: acc_public, acc_static
code:
stack=3, locals=1, args_size=1
0: getstatic #5 // field java/lang/system.out:ljava/io/printstream;
3: new #6 // class java/lang/stringbuilder
6: dup
7: invokespecial #7 // method java/lang/stringbuilder."<init>":()v
10: ldc #12 // string static hello,
12: invokevirtual #9 // method java/lang/stringbuilder.append:(ljava/lang/string;)ljava/lang/stringbuilder;
15: aload_0
16: invokevirtual #9 // method java/lang/stringbuilder.append:(ljava/lang/string;)ljava/lang/stringbuilder;
19: invokevirtual #10 // method java/lang/stringbuilder.tostring:()ljava/lang/string;
22: invokevirtual #11 // method java/io/printstream.println:(ljava/lang/string;)v
25: return
linenumbertable:
line 51: 0
line 52: 25
localvariabletable:
start length slot name signature
26 0 word ljava/lang/string;
}
sourcefile: "hello.java"
|
我们从字节码文件中可以看出来:
sayhello(string word) 和 sayhellostatic(string word) 都只有一个参数,但是在字节码中:
sayhello(string word) 中引用 word 时使用了 15: aload_1, 可以看出其加载的变量是在 slot1中,而 slot0中即保存了 this 。
sayhellostatic(string word) 中引用 word 时使用了 15: aload_0, 可以看出静态方法中,直接将变量存在了 slot0中,因此无法使用 this 中的变量了。
当要操作当前类的变量或方法时,需要先 aload_0, 然后再做相关操作!
总结:
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对快网idc的支持。
原文链接:http://www.cnblogs.com/yougewe/p/9929249.html
相关文章
- ASP.NET本地开发时常见的配置错误及解决方法? 2025-06-10
- ASP.NET自助建站系统的数据库备份与恢复操作指南 2025-06-10
- 个人网站服务器域名解析设置指南:从购买到绑定全流程 2025-06-10
- 个人网站搭建:如何挑选具有弹性扩展能力的服务器? 2025-06-10
- 个人服务器网站搭建:如何选择适合自己的建站程序或框架? 2025-06-10
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
-
2025-05-29 55
-
2025-05-25 31
-
2025-05-25 62
-
如何实现企业服务器的自动化部署和配置管理?有哪些推荐的工具和技术?
2025-05-25 40 -
2025-05-27 44

