Cai Xueqi column: All programmers in the world will make mistakes

zhaozj2021-02-08  277

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 1class Singleton {private static Singleton obj = new Singleton (); public static int counter1; public static int counter2 = 0; private Singleton () {counter1 ; counter2 ;} public static Singleton getInstance () {return obj;}}

// Program 2public 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 result is: obj.counter1 == 1obj.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 3Class Singleton {Private Static Singleton Obj; Public Static Int Counter1; Public Static Int Counter2; Static {// This is Class Constructor // Before entering this class constructor, Class has been configured by JVM //, all Static field will be set to 0, // So at this time, COUNTER1 and Counter2 are already 0, and singleton is null obj = new singleton (); // The problem is not here. It is set to 0 counter2 = 0; // counter2 is set again 0 (actually more this one)} private singleton () {// This is Instance Constructor 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 in the "= ..." mode 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 Instance Constructor is executed, 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 three: move the initialization action into the Class Constructors, write itself without relying on the compiler. This is the most insurance.

How to avoid committing a "all the incorrects all over the world", I have given the Java programmer's suggestion: , Directly observe the resulting results.

Below is the demonstration of I use Javap to reverse group translation programs:

C: /> javap -c -classpath. Singleton

Compiled from MyMain.javaclass Singleton extends java.lang.Object {public static int counter1; public static int counter2; public static Singleton 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.

Author: Tsai Yung Article Source: Sleepless 2.0 Issue Date: 03/10/2003

转载请注明原文地址:https://www.9cbs.com/read-781.html

New Post(0)