Why do we minimize the scope of local variables?

Keywords: Java

Hi, this article is going to talk about a small detail of Java: why do we minimize the scope of local variables?

Well-known people don't tell secrets. The inspiration for this article comes from Effective Java, which I have bought for a long time. The pages of this book are yellowing and have been branded with time, but I still haven't finished reading this book. I'm ashamed to say so.

Why? I always feel that the Chinese translation of this book is a bit clumsy and boring. Clearly feel that the author said very reasonable, but is unable to mention a little interest.

(after saying this sentence, I feel a bit out of touch with the translator of this book. After all, it's easier to share the spit and share the difficulty.)

Why should we say such nonsense, for fear that everyone will think it is not worth mentioning, but details often determine success or failure. You might as well read it in a more relaxed way. Anyway, I don't like highly talked articles. After reading, I can only sigh with emotion: "yes," but that's all.

Okay, let's get to the point.

String [] strs = {"Xie","peony","Jia Tian"};
List<String> list = Arrays.asList(strs);

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String s = (String) iterator.next();
    System.out.println(s);
}

list.add("Silent king two");
Iterator<String> iterator1 = list.iterator();
while (iterator.hasNext()) {
    String s = (String) iterator1.next();
    System.out.println(s);
}

Do you think there is a problem after you read the above code with the naked eye?

If you're not careful, it seems really hard to find the problem caused by "copy-paste": the iterator of the previous variable is used in the condition of the second while loop, rather than iterator 1 that it should use (the modification of the variable is omitted after pasting). This problem will cause the code to throw a java. lang. Unsupported OperationException error at run time.

To be honest, in the past ten years of knocking code, there has been little copy and paste. There are not many variables that have not been modified thoroughly since they are pasted, resulting in unexpected bug.

If we minimize the scope of variables, we can really reduce the errors caused by "copy-paste". For example, change the while loop to the for loop.

for (Iterator<String> iterator = list.iterator();iterator.hasNext();) {
    String s = (String) iterator.next();
    System.out.println(s);
}

list.add("Silent king two");
for (Iterator<String> iterator = list.iterator();iterator.hasNext();) {
    String s = (String) iterator.next();
    System.out.println(s);
}

The second for loops use exactly the same code as the first for loop, and even the iterator variable does not need to be modified.

On the other hand, for loops are shorter and more readable than while loops. For loops also have another most commonly used way of writing, as shown below.

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

But there is still room for improvement in this writing, because from the bytecode point of view, each loop calls the size() method once.

2: iload_1
3: aload_0
4: getfield      #4                  // Field list:Ljava/util/List;
7: invokeinterface #5,  1            // InterfaceMethod java/util/List.size:()I
12: if_icmpge     40
15: getstatic     #6                  // Field java/lang/System.out:Ljava/io/PrintStream;
18: aload_0
19: getfield      #4                  // Field list:Ljava/util/List;
22: iload_1
23: invokeinterface #7,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
28: checkcast     #8                  // class java/lang/String
31: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
34: iinc          1, 1
37: goto          2
40: return

Although the size() method is short, it also consumes. What are the costs? Say a few professional terms, you can feel, for example: create stack frame, protect the scene when calling method, restore the scene after calling method.

(Allow me to be embarrassed. Before I wrote this article, I used the above for loop format. It seems that writing articles can still push oneself forward.

How to improve it? Look at the following (strongly recommended).

for (int i = 0, n = list.size(); i < n; i++) {
    System.out.println(list.get(i));
}

Declare two variables inside the for loop: I and n, n to hold the limit value of i, which reduces the number of calls to the size() method (only once).

Let's look at another piece of code.

String pre_name = "silent";
String last_name = "WangTwo";

System.out.println(pre_name);
System.out.println(last_name);

The above code looks quite regular. There is nothing wrong with it, right? It does not follow the Convention of minimizing the scope of local variables.

The scope of the pre_name variable ends a little late; the scope of the last_name variable starts a little early. If the first System.out.println() goes wrong, the last_name declaration becomes meaningless.

(This is just an example of how variables can be handled much more complex than System.out.println().

Good writing should be the following.

String pre_name = "silent";
System.out.println(pre_name);

String last_name = "WangTwo";
System.out.println(last_name);

Does anyone think that this is not picky? No, variables should be declared the first time they are used. Otherwise, the scope of the variable either starts too early or ends too late.

Well, this article is over, very short, but it is clear why we should minimize the scope of local variables.

Posted by Nathan__02 on Sun, 06 Oct 2019 08:34:20 -0700