所有字节码都是用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
}