java for循环




为什么这个循环改变了? (3)

我刚刚遇到了我的类的反编译类文件:

我的课

while ((line = reader.readLine()) != null) {
    System.out.println("line: " + line);
    if (i == 0) {
        colArr = line.split(Pattern.quote("|"));

    } else {
        i++;
    }
}

while循环已更改为类文件中的for循环:

反编译MyClass

for (String[] colArr = null; (line = reader.readLine()) != null; ++i) {
    System.out.println("line: " + line);
    if (i == 0) {
        colArr = line.split(Pattern.quote("|"));
    } else {
    }
}

为什么这个循环被改为for ? 我认为它可能是编译器进行代码优化的另一种方式,我可能是错的。 我只是想知道它是否, for循环在while循环或其他循环中提供了什么优势?
这种代码优化的类别是什么?


for循环和while循环代码段都可以转换为类似的机器代码。 之后,当反编译时,解编译器必须选择two possible场景之一。

我想这就是这里发生的事情。

只是:

compile(A) -> C

compile(B) -> C

因此,当你获得C ,应该猜测选择AB


在这种情况下,将while()更改为for()不是优化。 根本无法从字节码中知道在源代码中使用了哪一个。

有很多情况:

while(x)

是相同的:

for(;x;)

假设我们有三个类似的java应用程序 - 一个带有while()语句,两个带有相应for() 。 第一个for()的停止标准仅在标准while() ,而第二个for()也用于迭代器声明和递增。

申请#1 - 来源

public class While{
    public static void main(String args[]) {
        int i = 0;
        while(i<5){
            System.out.println(i);
            i++;
        }
    }
}

申请#2 - 来源

public class For{
    public static void main(String args[]) {
        int i = 0;
        for(; i<5 ;){
            System.out.println(i);
            i++;
        }
    }
}

申请#3 - 来源

public class For2{
    public static void main(String args[]) {
        for(int i=0;i<5;i++){
            System.out.println(i);
        }
    }
}

如果我们编译所有这些,我们得到:

申请#1 - BYTECODE

public class While {
  public While();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: iconst_5
       4: if_icmpge     20
       7: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      10: iload_1
      11: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      14: iinc          1, 1
      17: goto          2
      20: return
}

申请#2 - BYTECODE

public class For {
  public For();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: iconst_5
       4: if_icmpge     20
       7: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      10: iload_1
      11: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
      14: iinc          1, 1
      17: goto          2
      20: return
}

申请#3 - BYTECODE

public class For2 extends java.lang.Object{
public For2();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   iconst_5
   4:   if_icmpge       20
   7:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   10:  iload_1
   11:  invokevirtual   #3; //Method java/io/PrintStream.println:(I)V
   14:  iinc    1, 1
   17:  goto    2
   20:  return

}

所以你可以看到,使用时和使用时没有任何区别。


这基本上是因为字节码的性质。 Java字节码就像汇编语言一样,因此没有forwhile循环这样的东西,只有跳转指令: goto 。 因此whilefor循环之间可能没有区别,两者都可以编译成类似的代码,而反编译器只是猜测。





optimization