我晕,怎么还有问这么古老的问题啊!两个!我证明给你看:public class Demo{ public static void main(String[] arg){ String s = new String("hello"); System.out.println(s==s.intern()); System.out.println("hello"==s.intern()); } } 输出结果为: false trueintern()方法是返回String常量池里面的字符串,由false可知它与s对象并不相等,但是却与字面量"hello"相等,说明常量池里面的那个"hello"和程序中的字面量"hello"都是编译器就已经加入常量池的同一个对象(编译器优化的结果)所以是两个对象
public class Test { public static void main(String[] args) { String s = new String("xyz"); }}javap 后结果(Java 虚拟机指令的反汇编形式):javap -c -l -private -s -verbose Test Compiled from "test.java" public class Test extends java.lang.Object SourceFile: "test.java" minor version: 0 major version: 50 Constant pool: const #1 = Method #6.#15; // java/lang/Object."<init>":()V const #2 = class #16; // java/lang/String const #3 = String #17; // xyz const #4 = Method #2.#18; // java/lang/String."<init>":(Ljava/lang/String;)V const #5 = class #19; // Test const #6 = class #20; // java/lang/Object const #7 = Asciz <init>; const #8 = Asciz ()V; const #9 = Asciz Code; const #10 = Asciz LineNumberTable; const #11 = Asciz main; const #12 = Asciz ([Ljava/lang/String;)V; const #13 = Asciz SourceFile; const #14 = Asciz test.java; const #15 = NameAndType #7:#8;// "<init>":()V const #16 = Asciz java/lang/String; const #17 = Asciz xyz; const #18 = NameAndType #7:#21;// "<init>":(Ljava/lang/String;)V const #19 = Asciz Test; const #20 = Asciz java/lang/Object; const #21 = Asciz (Ljava/lang/String;)V;{ public Test(); Signature: ()V LineNumberTable: line 1: 0 Code: Stack=1, Locals=1, Args_size=1 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); Signature: ([Ljava/lang/String;)V LineNumberTable: line 4: 0 line 5: 10 Code: Stack=3, Locals=2, Args_size=1 0: new #2; //class java/lang/String 3: dup 4: ldc #3; //String xyz 6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V 9: astore_1 10: return LineNumberTable: line 4: 0 line 5: 10 }注意这两行:Constant pool: const #3 = String #17; // xyzCode: 0: new #2; //class java/lang/String第一处:"xyz" 是作为常量池(Constant pool)中常量来处理的,这个 "xyz" 严格来讲不叫对象。 第二处:new 是创建对象的 JVM 指令,这个才是真正意义上(String 类)的对象创建。 所以:只创建了一个对象。
3个, “xyz” 1 New String() 1 String s 1
有两个 第一个即使String s 存放在内存中为STRING留的一块区域 而第二个是new string("xyz"); 在堆内存中存放。 但是二者有着引用的关系。
楼主【empty2008】截止到2008-07-13 18:04:46的历史汇总数据(不包括此帖):
发帖的总数量:0 发帖的总分数:0 每贴平均分数:0
回帖的总数量:1 得分贴总数量:0 回帖的得分率:0%
结贴的总数量:0 结贴的总分数:0
无满意结贴数:0 无满意结贴分:0
未结的帖子数:0 未结的总分数:0
结贴的百分比:---------------------结分的百分比:---------------------
无满意结贴率:---------------------无满意结分率:---------------------
如何结贴请参考这里:http://topic.csdn.net/u/20080501/09/ef7ba1b3-6466-49f6-9d92-36fe6d471dd1.html
java里面的对象都是放在heap中,引用是可以放到stack中的,所以说引用s是对象肯定是错误的说法,String s=new String("xyz");在编绎时会把"xyz"作为常量放到类的常量池中,运行时调用new指令时会再在堆中产生一个String类型的对象,把常量池中的"xyz"的值复制过来,然后让s指向堆中的String对象,所以应该是两个对象,一个是String类的Class对象中的常量字符串对象,一个是new出来的堆中的字符串对象.而String s="abc";则只产生了一个对象,就是String类的Class对象中的常量字符串对象,它只是让s指向了常量池中的那个常量字符串对象.
看来String类的确比较特殊,不过如何证明呢?10楼的朋友能给个办法吗?
public static void main(String[] arg){
String s = new String("hello"); System.out.println(s==s.intern());
System.out.println("hello"==s.intern());
}
}
输出结果为:
false
trueintern()方法是返回String常量池里面的字符串,由false可知它与s对象并不相等,但是却与字面量"hello"相等,说明常量池里面的那个"hello"和程序中的字面量"hello"都是编译器就已经加入常量池的同一个对象(编译器优化的结果)所以是两个对象
String s = new String("xyz");
}}javap 后结果(Java 虚拟机指令的反汇编形式):javap -c -l -private -s -verbose Test
Compiled from "test.java"
public class Test extends java.lang.Object
SourceFile: "test.java"
minor version: 0
major version: 50
Constant pool:
const #1 = Method #6.#15; // java/lang/Object."<init>":()V
const #2 = class #16; // java/lang/String
const #3 = String #17; // xyz
const #4 = Method #2.#18; // java/lang/String."<init>":(Ljava/lang/String;)V
const #5 = class #19; // Test
const #6 = class #20; // java/lang/Object
const #7 = Asciz <init>;
const #8 = Asciz ()V;
const #9 = Asciz Code;
const #10 = Asciz LineNumberTable;
const #11 = Asciz main;
const #12 = Asciz ([Ljava/lang/String;)V;
const #13 = Asciz SourceFile;
const #14 = Asciz test.java;
const #15 = NameAndType #7:#8;// "<init>":()V
const #16 = Asciz java/lang/String;
const #17 = Asciz xyz;
const #18 = NameAndType #7:#21;// "<init>":(Ljava/lang/String;)V
const #19 = Asciz Test;
const #20 = Asciz java/lang/Object;
const #21 = Asciz (Ljava/lang/String;)V;{
public Test();
Signature: ()V
LineNumberTable:
line 1: 0 Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
public static void main(java.lang.String[]);
Signature: ([Ljava/lang/String;)V
LineNumberTable:
line 4: 0
line 5: 10 Code:
Stack=3, Locals=2, Args_size=1
0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String xyz
6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: return
LineNumberTable:
line 4: 0
line 5: 10
}注意这两行:Constant pool:
const #3 = String #17; // xyzCode:
0: new #2; //class java/lang/String第一处:"xyz" 是作为常量池(Constant pool)中常量来处理的,这个 "xyz" 严格来讲不叫对象。
第二处:new 是创建对象的 JVM 指令,这个才是真正意义上(String 类)的对象创建。
所以:只创建了一个对象。
“xyz” 1
New String() 1
String s 1
第一个即使String s 存放在内存中为STRING留的一块区域
而第二个是new string("xyz"); 在堆内存中存放。
但是二者有着引用的关系。
彻底无语,请看看《JVM规范》!!!