Java 编译器是否删除了不必要的括号

Java 编译器是否删除了不必要的括号,java,compiler-construction,Java,Compiler Construction,例如,如果我在Eclipse中用Java编译这个 intvar = (int)(((var1 * var3))*(7)); 编译器会将其清理到 intvar = (int) var1 * var3 * 7; 然后编译器会把它变成机器代码之类的东西 或者我必须对编译器做一些特殊的事情来优化代码 此外,这是否适用于所有其他编译的语言?编译器将java代码转换为字节码。字节码根本没有括号。它与堆栈一起工作。使用javap-c检查字节码: intvar = (int)(((var1 * var3))

例如,如果我在Eclipse中用Java编译这个

intvar = (int)(((var1 * var3))*(7));
编译器会将其清理到

intvar = (int) var1 * var3 * 7;
然后编译器会把它变成机器代码之类的东西

或者我必须对编译器做一些特殊的事情来优化代码


此外,这是否适用于所有其他编译的语言?

编译器将java代码转换为字节码。字节码根本没有括号。它与堆栈一起工作。

使用
javap-c检查字节码:

intvar = (int)(((var1 * var3))*(7));
变成:

   4: iload_1       
   5: iload_2       
   6: imul          
   7: bipush        7
   9: imul          
  10: istore_3      
   4: iload_1       
   5: iload_2       
   6: imul          
   7: bipush        7
   9: imul          
  10: istore_3      

变成:

   4: iload_1       
   5: iload_2       
   6: imul          
   7: bipush        7
   9: imul          
  10: istore_3      
   4: iload_1       
   5: iload_2       
   6: imul          
   7: bipush        7
   9: imul          
  10: istore_3      
i、 完全相同。

编译器删除所有括号。如果所有操作数都是整数,则从JLS和编译器的角度来看,这两条语句是相同的

但是如果你写过

intvar = (int)((var1*(var2*7)))

所需的执行顺序不同,因此会得到不同的字节码。

括号实际上不会生成代码。它们不是行动。括号只是控制代码的输出顺序,或者更确切地说,控制操作的执行顺序。因此,不必担心“不必要的”括号,除非顺序影响结果(例如,由于括号的方式,操作突然以浮点而不是整数执行)。

第二行与第一行不同。例如,如果
var3
double
,则第二行的结果是
double
。在第一行中,相同条件下的结果将是
int
让我们说,我从不使用双精度浮点运算,但大多数情况下使用浮点运算。第二行使用(int)oops是没有意义的。我只是想用并列的例子,而不是那些东西,我希望我能在编译后看到代码that@androidmaster但是你可以!只需使用
javap-csomefile
。这怎么可能呢???我必须使用sdk还是eclipse中有选项?所以我们使用哪一个更容易阅读,对吗?@androidmaster从终端或命令行运行该命令,无论您有哪一个。@androidmaster您在命令行上使用
javap
。如果您在Eclipse上,请尝试(这是我使用的,非常方便)。这是错误的答案。首先,编译器将代码转换为树,然后对代码进行优化(如删除因其生成的类型而产生的不必要的强制转换),然后将其转换为字节码。@libik我们可以说这个答案是编译器在幕后遵循的整个复杂过程的抽象吗?那么我们可以说,这个抽象没有错吗?@RohitJain-当然,你有没有试过做以下事情:创建你自己的语言,然后创建你自己的编译器将其转换为你自己的字节码转换,然后创建能够运行它的虚拟机?是的。我可以告诉你——即使它被转换成字节码,如果没有优化,它也可能包含冗余。libik你创建的语言的名称是什么?@ibik这个答案没有错。您提供了关于它的更多细节,其中一些可能适用于或不适用于特定的Java编译器。然而,上面所说的答案并没有错误。在这种情况下,括号并不是“不必要的”。