2013-03-08 86 views
4

什么是使用这个的利弊:存储在变量对具有多个不同的方法

String a = new String(); 
switch (i) { 
case 1: a = "Cueck"; break; 
case 2: a = "Blub"; break; 
case 3: a = "Writing cases is BORING!"; break; 
} 
System.out.println(a); 

对战:

switch (i) { 
case 1: System.out.println("Cueck"); break; 
case 2: System.out.println("Blub"); break; 
case 3: System.out.println("Writing cases is BORING!"); break; 
} 

产生更好的字节码?而哪个产生更多的字节码?

+3

我建议你获取ASM字节码大纲并自己测试一下。 :) – PermGenError 2013-03-08 09:50:56

+0

第一个将结果存储在变量中。 – nullpotent 2013-03-08 09:51:17

+2

我不会担心它,除非它被执行了420亿次......这个问题仅仅是为了理论,还是为了一个真正的问题? – vikingsteve 2013-03-08 09:51:37

回答

4

使用javap -c classname您可以检查自己的字节码,

这里的选项1:

(注意,我不得不初始化a = null否则它不会编译)

7: aconst_null 
    8: astore_2 
    9: iload_1 
    10: tableswitch{ //1 to 3 
       1: 36; 
       2: 42; 
       3: 48; 
       default: 51 } 
    36: ldc  #3; //String Cueck 
    38: astore_2 
    39: goto 51 
    42: ldc  #4; //String Blub 
    44: astore_2 
    45: goto 51 
    48: ldc  #5; //String Writing cases is BORING! 
    50: astore_2 
    51: getstatic  #6; //Field java/lang/System.out:Ljava/io/PrintStream; 
    54: aload_2 
    55: invokevirtual #7; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    58: return 

这里的选项2 :

7: iload_1 
    8: tableswitch{ //1 to 3 
       1: 36; 
       2: 47; 
       3: 58; 
       default: 66 } 
    36: getstatic  #3; //Field java/lang/System.out:Ljava/io/PrintStream; 
    39: ldc  #4; //String Cueck 
    41: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    44: goto 66 
    47: getstatic  #3; //Field java/lang/System.out:Ljava/io/PrintStream; 
    50: ldc  #6; //String Blub 
    52: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    55: goto 66 
    58: getstatic  #3; //Field java/lang/System.out:Ljava/io/PrintStream; 
    61: ldc  #7; //String Writing cases is BORING! 
    63: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    66: return 

就我个人而言,我认为在这个例子中有更好的字节码,我发现选项1更具可读性。

4

我不认为在字节码大小上会有太大的差别,但我建议第一种方法。如果您在将来的某些代码更改决定不调用System.out.println(a)而是logger.debug(a),则只会在一个地方而不是所有的case开关上更改该代码。

5

您的第一个选项是整洁,代码少。提出的一种变化:

String a; 

switch (i) { 
    case 1: a = "Cueck"; break; 
    case 2: a = "Blub"; break; 
    case 3: a = "Writing cases is BORING!"; break; 
    default: throw new IllegalStateException("Unknown option!"); 
} 

System.out.println(a); 

不要创建不必要的字符串 - 需要时a应instatiated。默认情况下应该抛出异常或将a设置为默认值。

哪个生成更好的字节码?而哪个产生更多的字节码?

我不会为此担心。这并不意味着我可能成为任何实际应用程序的瓶颈。另外,一旦应用程序运行,您无法确定JVM将如何优化字节码。

+3

也不要使用[String interning](http://en.wikipedia.org/wiki/String_interning)调用'new String()'。 – 2013-03-08 10:00:00

+0

@ bmorris591你有参考吗? – 2013-03-08 10:05:48

+0

我只是说,如果你直接调用构造函数,'String'不会被实现,从[spec](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html )只有“编译时间常量”字符串被实施。 – 2013-03-08 12:38:49

相关问题