Declaring variables inside or outside of a loop

前端 未结 20 2079
后悔当初
后悔当初 2020-11-22 01:59

Why does the following work fine?

String str;
while (condition) {
    str = calculateStr();
    .....
}

But this one is said to be dangerou

20条回答
  •  情话喂你
    2020-11-22 02:40

    I compared the byte code of those two (similar) examples:

    Let's look at 1. example:

    package inside;
    
    public class Test {
        public static void main(String[] args) {
            while(true){
                String str = String.valueOf(System.currentTimeMillis());
                System.out.println(str);
            }
        }
    }
    

    after javac Test.java, javap -c Test you'll get:

    public class inside.Test extends java.lang.Object{
    public inside.Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."":()V
       4:   return
    
    public static void main(java.lang.String[]);
      Code:
       0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
       3:   invokestatic    #3; //Method java/lang/String.valueOf:(J)Ljava/lang/String;
       6:   astore_1
       7:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
       10:  aload_1
       11:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       14:  goto    0
    
    }
    

    Let's look at 2. example:

    package outside;
    
    public class Test {
        public static void main(String[] args) {
            String str;
            while(true){
                str =  String.valueOf(System.currentTimeMillis());
                System.out.println(str);
            }
        }
    }
    

    after javac Test.java, javap -c Test you'll get:

    public class outside.Test extends java.lang.Object{
    public outside.Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."":()V
       4:   return
    
    public static void main(java.lang.String[]);
      Code:
       0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
       3:   invokestatic    #3; //Method java/lang/String.valueOf:(J)Ljava/lang/String;
       6:   astore_1
       7:   getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
       10:  aload_1
       11:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       14:  goto    0
    
    }
    

    The observations shows that there is no difference among those two examples. It's the result of JVM specifications...

    But in the name of best coding practice it is recommended to declare the variable in the smallest possible scope (in this example it is inside the loop, as this is the only place where the variable is used).

提交回复
热议问题