62,614
社区成员
发帖
与我相关
我的任务
分享
public static void main(String[] args) {
String nnn = new String("abcd"+"xyz");
}
我这里看没有优化啊
public static void main(java.lang.String[] args);
0 new java.lang.String [16]
3 dup
4 ldc <String "abcdxyz"> [18]
6 invokespecial java.lang.String(java.lang.String) [20]
9 astore_1 [nnn]
10 return
Line numbers:
[pc: 0, line: 9]
[pc: 10, line: 11]
Local variable table:
[pc: 0, pc: 11] local: args index: 0 type: java.lang.String[]
[pc: 10, pc: 11] local: nnn index: 1 type: java.lang.String
[/quote]
public static void main(java.lang.String[] args);
0 new java.lang.String [24]
3 dup
4 ldc <String "abc+dbc"> [26]
6 invokespecial java.lang.String(java.lang.String) [28]
9 astore_1 [s]
10 return
Line numbers:
[pc: 0, line: 13]
[pc: 10, line: 17]
Local variable table:
[pc: 0, pc: 11] local: args index: 0 type: java.lang.String[]
[pc: 10, pc: 11] local: s index: 1 type: java.lang.Stringclass T
{
String name= new String("java"+"hello");
}
T.class反编译后:
E:\>javap -verbose T
Compiled from "T.java"
class T extends java.lang.Object
SourceFile: "T.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #7.#16; // java/lang/Object."<init>":()V
const #2 = class #17; // java/lang/String
const #3 = String #18; // javahello
const #4 = Method #2.#19; // java/lang/String."<init>":(Ljava/lang/String
;)V
const #5 = Field #6.#20; // T.name:Ljava/lang/String;
const #6 = class #21; // T
const #7 = class #22; // java/lang/Object
const #8 = Asciz name;
const #9 = Asciz Ljava/lang/String;;
const #10 = Asciz <init>;
const #11 = Asciz ()V;
const #12 = Asciz Code;
const #13 = Asciz LineNumberTable;
const #14 = Asciz SourceFile;
const #15 = Asciz T.java;
const #16 = NameAndType #10:#11;// "<init>":()V
const #17 = Asciz java/lang/String;
const #18 = Asciz javahello;
const #19 = NameAndType #10:#23;// "<init>":(Ljava/lang/String;)V
const #20 = NameAndType #8:#9;// name:Ljava/lang/String;
const #21 = Asciz T;
const #22 = Asciz java/lang/Object;
const #23 = Asciz (Ljava/lang/String;)V;
{
java.lang.String name;
T();
Code:
Stack=4, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: new #2; //class java/lang/String
8: dup
9: ldc #3; //String javahello
11: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/Strin
g;)V
14: putfield #5; //Field name:Ljava/lang/String;
17: return
LineNumberTable:
line 1: 0
line 3: 4
}
string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下
string之间+:是new了一个StringBuilder,然后调用它的append()方法完成的,所以String name=new String(“hello”)和String name=new String(“hello”+“java”)产生的对象都是2个。自己可以用javap -c ClassName查看一下
2个好不好
[root@hina stringtest]# more TestString.java
public class TestString{
public static void main(String[] args) {
String name = new String("java" + "hello");
}
}
[root@hina stringtest]# javac TestString.java
[root@hina stringtest]# javap -c TestString
上面这段javap -c打编译后的字节码
插一句,论坛里多数是靠java吃饭的,如果不看下面的内容,对编译的字节码没有一个大概的结论,那你们未免太不把自己的工作和前途当一回事了。
Compiled from "TestString.java"
public class TestString extends java.lang.Object{
public TestString();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String javahello
6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: return
}
看清楚了,编译的字节码里没有java也没有hello,而是javahello。这个javahello不是在执行的时候被创建,而是jvm启动的时候初始化好的。
实际上只有一个new,也就是说只创建了一个对象:
0 new 创建string对象
3 dup 复制顶栈内容,这是所有new对象都会做的事情,因为jvm要做<init>
4 ldc 把常量池中javahello的引用压入栈中
6 invokespecial 对象初始化
9 astore_1 把栈中的引用赋给第一个变量