2013-03-08 54 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

相關問題