At that year, the international superstar Jackie Chan's "Dragon" exposure, everyone accused him to face the wife Lin Fengjiao, forced him to come to hold a reporter meeting, to the world, he made "all men who will commit" all men in the world ". I have never committed this mistake, and I often think that I am not a man.
Although I didn't commit "all men who made people in the world", I have committed the "mistakes" all the programs all over the world. " Regardless of the language of use, all programmers around the world must have made this mistake, that is: too dependent on the compiler, but I don't know what the compiler did.
In general, the higher-level programming language will provide more grammar to facilitate the program, which is commonly known as syntactic sugar, I call it "Sweets on the grammat". Although it is sweet, if you have failed to understand the essence of the syntax, it is likely that there is no sweetener, but it is suffering.
Not long ago, I received an email, the reader lists the Java programs below, saving me. After reading this program, I am sure this is a "all the mistakes all of the world" will be made. "
// Program 1
Class singleton {
Private static singleleton obj = new singleleton ();
Public static int counter1;
Public static int counter2 = 0;
Private singleton () {
Counter1 ;
Counter2 ;
}
Public static singleleton getinstance () {
Return Obj;
}
}
// Program 2
Public class mymain {
Public static void main (String [] args) {
Singleton Obj = Singleton.getInstance ();
System.out.println ("obj.counter1 ==" Obj.counter1);
System.out.println ("obj.counter2 ==" Obj.counter2);
}
}
The execution result is:
Obj.counter1 == 1
Obj.counter2 == 0
Have you been scared by this result? At first glance, you are likely to think that the value of Counter1 and Counter2 will be equal, but the implementation results are obviously not the case. In fact, the program 1 after compiled procedures should be equivalent to the following program 3:
// Program 3
Class singleton {
Private static singleleton obj;
Public static int counter1;
Public static int counter2;
Static {// this is Class Constructor
// Class Class has been JVM before entering this Class Constructionor
// Configure memory, all Static Field will be set to 0 first.
// So at this time, Counter1 and Counter2 are already 0, and Singleton is NULL.
Obj = new singleton (); // The problem is generated by this line program
// counter1 will not be set here to 0
Counter2 = 0; // counter2 is set again 0 (actually more this)
}
Private singleton () {// This is Instance Constructionor
Counter1 ; counter2 ;
}
Public static singleleton getinstance () {
Return Obj;
}
}
This is because: When the Class has Static Field, the compiler will automatically move these narratives in the Class Constructor when the value is set directly through "= ...". Similarly, when the Class has an Instance Field, the compiler will automatically move these narratives in the instance constructor while setting the value in the declaration of "= ...".
This program has not initialized Static Field in Class Constructor (this time, counter1 and counter2 are 0), call Instance Constructor, and instance constructor will also go to the value of Static Field, make Counter1 and Counter2 Getting 1. Then the instance constructor is completed, go back to the class constructor, then set the value of counter2 to 0 (but
Counter1 remains unchanged). The last result: Counter1 is equal to 1, and counter2 is equal to 0.
To correct the procedure 1, the method has three:
- Method 1: Turn the declaration of Singleton Field to Counter1 and Counter2 Field.
This is the best practice.
- Method 2: During the declaration of Counter2 = 0, the "= 0" part is deleted. This method is only in hope
- Method 3: Move the initialization action to the Class Constructors, write itself, not dependence
The compiler is generated. This is the most insurance.
How to avoid committing a mistake of all programmers all over the world, I give you a Java programmer
Suggestions are:
- Reading Java Language Specification
- When having questions, use JavaP provided by J2SDK to reversely translate Java Bytecode, directly observe
Compiled results.
Below is the demonstration of I use Javap to reverse group translation programs:
C:> javap -c -classpath. Singleton
Compiled from mymain.java
Class Singleton Extends Java.lang.Object {
Public static int counter1;
Public static int counter2;
Public static singleleton getinstance ();
STATIC {};
}
Method Singleton ()
0 ALOAD_0
1 InvokeSpecial # 1
4 getStatic # 2
7 iconst_1
8 IADD
9 PutStatic # 2
12 getStatic # 3
15 iconst_1
16 Iadd
17 PutStatic # 3
20 return
Method Singleton getInstance ()
0 getStatic # 4
3 areeturn
Method static {}
0 new # 5
3 dup
4 InvokeSpecial # 6
7 PutStatic # 4
10 iconst_0
11 PutStatic # 3
14 return
In fact, Java's syntactic sugar is not much, C # Syntactic Sugar is really omnipotent, and therefore, C # beginners are easier to commit "all programmers all over the world will make mistakes". Many C # books will introduce the C # syntax, while describing the results of MSIL (.NET intermediate language, similar java's Bytecode), Java's book is so fresh.
Although it is "all the mistakes all of the world will make a mistake", but this does not mean that you have made this mistake, you can still "look up at Cao Qitai with love to borrow money." As long as you have an heart, this is still avoidable.
__________________
Insight, the auto-eye, seeking truth from facts