Supporting video:
Why recommend learning Java bytecode
https://www.bilibili.com/video/av77600176/
I. Background
This paper discusses: Why learn JVM bytecode?
Many people may feel no need to, because usually develop with less, and do not learn this did not delay learning.
But here to share that sentiment, that is, people always here to solve problems according to their knowledge and skills have been mastered.
Here is a paradox, sometimes you feel a little useless technology just because you do not master it, you can use it encounters a scene you would not think to use .
1.1 From the perspective of life in terms of
If you are a non-computer science students, your teacher give you a few pictures of books, about 3,000 words, let you print into text.
You turn on the computer, crackling meal knock out the afternoon was done.
If you know the voice input, then you may be by way of voice input, 30 minutes to get.
If you know the pictures OCR text recognition, could get five minutes.
Different methods, the effect brought about entirely different. However, the most frightening thing is that you do not voice input or OCR you will not feel less Han.
OCR recognition is definitely not improve your typing speed can point to catch up on.
1.2 learning Java angle
Many people learn rely mainly on Baidu, rely blog, video and books rely on, and these data of varying quality, and are the result after the others understand.
For example, you usually do not see the source code , then you will rarely be able to source material as you learn, can only rely blog, books, videos and so on.
If you usually like to look at the source code, you will have your own understanding of the source code, you will find that there are a lot of source code to help you learn.
If you usually do not compile with anti-decompile and then you have to rely more source code, debugging and other dependent learning knowledge, not from the bytecode level to learn and understand knowledge.
When you read slowly skilled virtual machine instructions, you will find you a way to learn more knowledge.
Second, why should learn bytecode
2.1 People are always reluctant to leave the comfort zone
Many people in learning new knowledge, always instinctively conflict. Will find a variety of reasons do not learn, "such as being less than", "learn futile," "a later date."
Even I thought it was a waste of time.
2.2 Why learn bytecode?
Recently learned about some time JVM bytecode, though not proficient, but read byte code it has been less difficult.
Why recommend learning byte code because it can be a deeper level than the source of knowledge to learn Java.
, But it gives you a way to learn though unlikely that all problems are with the knowledge to solve bytecode.
For example, by learning bytecode you can better understand the various principles of Java syntax and grammar sugar behind a better understanding of language features and polymorphism.
Third, for example
Herein cite a simple example to illustrate the effect of learning bytecode.
3.1 Examples
3.1.1 syntactic sugar
public class ForEachDemo {
public static void main(String[] args) {
List<String> data = new ArrayList<>();
data.add("a");
data.add("b");
for (String str : data) {
System.out.println(str);
}
}
}
Compiler: javac ForEachDemo.java
Disassembly: javap -c ForEachDemo
public class com.imooc.basic.learn_source_code.local.ForEachDemo {
public com.imooc.basic.learn_source_code.local.ForEachDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
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: ldc #4 // String a
11: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
16: pop
17: aload_1
18: ldc #6 // String b
20: invokeinterface #5, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
25: pop
26: aload_1
27: invokeinterface #7, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
32: astore_2
33: aload_2
34: invokeinterface #8, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
39: ifeq 62
42: aload_2
43: invokeinterface #9, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
48: checkcast #10 // class java/lang/String
51: astore_3
52: getstatic #11 // Field java/lang/System.out:Ljava/io/PrintStream;
55: aload_3
56: invokevirtual #12 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
59: goto 33
62: return
}
We can clearly see the bottom of the foreach loop uses an iterator to achieve, or even reverse brain fill out the corresponding Java source code (you can try to write equivalent according to the source byte code).
One problem encountered in 3.1.2 to read source code
We often encounter such an approach similar to the following when reading the source code:
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#startWebServer
private WebServer startWebServer() {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.start();
}
return webServer;
}
A declaration of local variables and member variables of the same name in a function, and then assign member variables to local variables go use.
Seemingly small detail, implies an optimization ideas.
Some people may have read some of the articles mentioned ( but why we gotta see a post will a knowledge? If you do not see how to do? ), More people may not understand what optimization.
3.2 Analog
Common syntactic sugar here is not to do too much expansion, we will talk about a second optimization example.
Examples of the above-described imitation wording :
public class LocalDemo {
private List<String> data = new ArrayList<>();
public void someMethod(String param) {
List<String> data = this.data;
if (data != null && data.size() > 0 && data.contains(param)) {
System.out.println(data.indexOf(param));
}
}
}
Compiler: javac LocalDemo.java
Disassembly: javap -c LocalDemo
public class com.imooc.basic.learn_source_code.local.LocalDemo {
public com.imooc.basic.learn_source_code.local.LocalDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #2 // class java/util/ArrayList
8: dup
9: invokespecial #3 // Method java/util/ArrayList."<init>":()V
12: putfield #4 // Field data:Ljava/util/List;
15: return
public void someMethod(java.lang.String);
Code:
0: aload_0
1: getfield #4 // Field data:Ljava/util/List;
4: astore_2
5: aload_2
6: ifnull 41
9: aload_2
10: invokeinterface #5, 1 // InterfaceMethod java/util/List.size:()I
15: ifle 41
18: aload_2
19: aload_1
20: invokeinterface #6, 2 // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
25: ifeq 41
28: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
31: aload_2
32: aload_1
33: invokeinterface #8, 2 // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
38: invokevirtual #9 // Method java/io/PrintStream.println:(I)V
41: return
}
At this time, the local variable table 0 is this, 1 is a local variable data param 2
Examples of direct use of member variables :
public class ThisDemo {
private List<String> data = new ArrayList<>();
public void someMethod(String param) {
if (data != null && data.size() > 0 && data.contains(param)) {
System.out.println(data.indexOf(param));
}
}
}
Compiler: javac ThisDemo.java
Disassembly: javap -c ThisDemo
public class com.imooc.basic.learn_source_code.local.ThisDemo {
public com.imooc.basic.learn_source_code.local.ThisDemo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #2 // class java/util/ArrayList
8: dup
9: invokespecial #3 // Method java/util/ArrayList."<init>":()V
12: putfield #4 // Field data:Ljava/util/List;
15: return
public void someMethod(java.lang.String);
Code:
0: aload_0
1: getfield #4 // Field data:Ljava/util/List;
4: ifnull 48
7: aload_0
8: getfield #4 // Field data:Ljava/util/List;
11: invokeinterface #5, 1 // InterfaceMethod java/util/List.size:()I
16: ifle 48
19: aload_0
20: getfield #4 // Field data:Ljava/util/List;
23: aload_1
24: invokeinterface #6, 2 // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
29: ifeq 48
32: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
35: aload_0
36: getfield #4 // Field data:Ljava/util/List;
39: aload_1
40: invokeinterface #8, 2 // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
45: invokevirtual #9 // Method java/io/PrintStream.println:(I)V
48: return
}
At this time, only two local variable table, i.e. this and param.
We can also view more detailed information javap -c -v, screenshots used in this example IDEA plug-in for jclasslib bytecode Viewer , refer to my interest in another article on this blog tools: " IDEA bytecode learning View artifact jclasslib bytecode viewer presentation . "
3.3 Analysis
By Source In fact, we are not well understood in the end where optimized.
We were two classes to compile and disassembly can be clearly seen: the first example code for more than a line, but after decompile bytecode shorter .
The second example after decompile bytecode longer than the first example where is it?
We found more in the main: the getfield # 4 // Field, the Data: Ljava / util / List; here .
That is, each acquiring data objects must first aload_0 then getfield instruction fetch.
Astore_2 first example by which to keep the local variable table, each with a direct aload_2 loaded directly from the local variable table to the operand stack.
Thereby eliminating the need always get the property from this object, and therefore more efficient.
This idea a bit like writing code commonly used in the cache, the data is about to be used recently to check once cached, priority check cache use.
Embodies the concept of locality and temporal locality space operating system (do not know if the next book or turn down Baidu) in nature .
Therefore, by analyzing bytecode, by contacting the actual development experience, by contacting the expertise, the problem we figured it out .
In addition also it reflects the idea of using space for time .
Only through them can the knowledge, understanding can be more secure.
Here also reflects the importance of professional basis.
In addition knowledge can be linked to the nature of thinking, in order to understand more deeply, memory can be more secure, more likely to be applied flexibly.
IV Summary
This is just a very typical example, learning JVM bytecode can give you a different perspective, you make one more way of learning.
Many people may say they want to learn but can not start, look here, we recommend the "in-depth understanding of the Java Virtual Machine" and then combine "Java Virtual Machine Specification", usually more knock javap instruction, slowly familiar, another highly recommended jclasslib bytecode viewer plug-in that you can click to jump to the instruction section describes the Java virtual machine specification of the instruction, learning a great help.
A lot of people might say, this is too slow to learn.
Indeed, how can you be so anxious to learn especially good? Plot to thin thick hair, how can it learn something lost and lonely.
In this paper, an example of which allow us to understand, JVM bytecode can help you understand some of Java's syntax (limited space and too many examples, here is not given, interested students try it yourself), and even help you learn Source.
Imagine, if you think learning bytecode useless, even if you do not understand, how can you use it to solve the problem?
You have the knowledge to help you grow your growth by the limits, to dare to break the comfort zone, give yourself more opportunities for growth.
-------------------
Welcome thumbs up, comment, forwarding, your encouragement, is the driving force of my work.