所有字节码都是用sun虚拟机编译的.以下内容都是在网上查阅,加上一些自己的分析,如果有不对之处请大家指出来.
1,循环外内定义变量 和 循环内定义变量
下面是代码和字节码,通过比较可以知道,两种方法字节码基本上是相同的.两者性能基本上相等.
在实际使用时建议根据语义来决定,不需要在循环外部使用的就定义在循环内部,这样也可以减少变量冲突的可能.
代码:
public static void f1() { Object s; for (int i = 0; i < 10; i++) { s = new String("sss"); } } public static void f2() { for (int i = 0; i < 10; i++) { Object s = new String("sss"); } }
字节码:
public static void f1() { // 0 0:iconst_0 // 1 1:istore_1 // 2 2:goto 18 // 3 5:new #15 <Class String> // 4 8:dup // 5 9:ldc1 #17 <String "sss"> // 6 11:invokespecial #19 <Method void String(String)> // 7 14:astore_0 // 8 15:iinc 1 1 // 9 18:iload_1 // 10 19:bipush 10 // 11 21:icmplt 5 // 12 24:return } public static void f2() { // 0 0:iconst_0 // 1 1:istore_0 // 2 2:goto 18 // 3 5:new #15 <Class String> // 4 8:dup // 5 9:ldc1 #17 <String "sss"> // 6 11:invokespecial #19 <Method void String(String)> // 7 14:astore_1 // 8 15:iinc 0 1 // 9 18:iload_0 // 10 19:bipush 10 // 11 21:icmplt 5 // 12 24:return }
2, 字符串String相加 和 StringBuffer相加
String相加在虚拟机内部还是采用StringBuffer来实现的,但是字节码指令上相比直接采用StringBuffer来说增加了不少.
代码:
public void f1() { String a = ""; a += "a"; a += "b"; a += "c"; System.out.println(a); } public void f2() { StringBuffer ab = new StringBuffer(); ab.append("a"); ab.append("b"); ab.append("c"); System.out.println(ab); }
字节码:
public void f1() { // 0 0:ldc1 #15 <String ""> // 1 2:astore_1 // 2 3:new #17 <Class StringBuffer> // 3 6:dup // 4 7:aload_1 // 5 8:invokestatic #19 <Method String String.valueOf(Object)> // 6 11:invokespecial #25 <Method void StringBuffer(String)> // 7 14:ldc1 #28 <String "a"> // 8 16:invokevirtual #30 <Method StringBuffer StringBuffer.append(String)> // 9 19:invokevirtual #34 <Method String StringBuffer.toString()> // 10 22:astore_1 // 11 23:new #17 <Class StringBuffer> // 12 26:dup // 13 27:aload_1 // 14 28:invokestatic #19 <Method String String.valueOf(Object)> // 15 31:invokespecial #25 <Method void StringBuffer(String)> // 16 34:ldc1 #38 <String "b"> // 17 36:invokevirtual #30 <Method StringBuffer StringBuffer.append(String)> // 18 39:invokevirtual #34 <Method String StringBuffer.toString()> // 19 42:astore_1 // 20 43:new #17 <Class StringBuffer> // 21 46:dup // 22 47:aload_1 // 23 48:invokestatic #19 <Method String String.valueOf(Object)> // 24 51:invokespecial #25 <Method void StringBuffer(String)> // 25 54:ldc1 #40 <String "c"> // 26 56:invokevirtual #30 <Method StringBuffer StringBuffer.append(String)> // 27 59:invokevirtual #34 <Method String StringBuffer.toString()> // 28 62:astore_1 // 29 63:getstatic #42 <Field PrintStream System.out> // 30 66:aload_1 // 31 67:invokevirtual #48 <Method void PrintStream.println(String)> // 32 70:return } public void f2() { // 0 0:new #17 <Class StringBuffer> // 1 3:dup // 2 4:invokespecial #55 <Method void StringBuffer()> // 3 7:astore_1 // 4 8:aload_1 // 5 9:ldc1 #28 <String "a"> // 6 11:invokevirtual #30 <Method StringBuffer StringBuffer.append(String)> // 7 14:pop // 8 15:aload_1 // 9 16:ldc1 #38 <String "b"> // 10 18:invokevirtual #30 <Method StringBuffer StringBuffer.append(String)> // 11 21:pop // 12 22:aload_1 // 13 23:ldc1 #40 <String "c"> // 14 25:invokevirtual #30 <Method StringBuffer StringBuffer.append(String)> // 15 28:pop // 16 29:getstatic #42 <Field PrintStream System.out> // 17 32:aload_1 // 18 33:invokevirtual #56 <Method void PrintStream.println(Object)> // 19 36:return }