Topic: 创建String对象的问题

  Print this page

1.创建String对象的问题 Copy to clipboard
Posted by: javahum
Posted on: 2005-12-11 16:58

question1:String s1="aa";创建了几个String对象?String s2=new String("aa");又创建了几个String对象?两句话有什么区别?
question2: String s1="aa" ;String s2="aa" 创建了几个String对象?String s1=new String("aa"); String s2=new String("aa");又创建了几个对象??

question3:
//////test equals and == Test1.java
class Test1{
pulic static void main(String []args){
String s1=new String("aa");
String s2=new String("aa");
System.out.println("s1==s2"+(s1==s2));
System.out.println("s1.equals(s2)"+s1.equals(s2));
}
}
--------------result:---------------

s1==s2false
s1.equals(s2)true


class Test2{
pulic static void main(String []args){
String s1="aa"
String s2="aa"
System.out.println("s1==s2"+(s1==s2));
System.out.println("s1.equals(s2)"+s1.equals(s2));
}
}
------------result--------

s1==s2true
s1.equals(s2)true

Do explain why it is so here ????

2.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: hamlet
Posted on: 2005-12-11 22:00

question1:
字符串在java里是一个特性,String s ="aa";不是几个对象的问题~你要搞明白引用和对象的关系,这条语句声明变量s是一个可以指向String类型的引用,而aa是真正的String类型的对象,所以s是现在指向的是一个Sting类型的对象。这是一种特殊的初始化方式。
而String s2=new String("aa");则是正常的初始化方式。实例化一个String对象其内容为"aa",然后声明了一个可以指向String 类型的引用,然后死s2指向哪个对象。

question2:
question1已经包含了question2了吧!!

question3:
String s1=new String("aa");
String s2=new String("aa");
System.out.println("s1==s2"+(s1==s2));
System.out.println("s1.equals(s2)"+s1.equals(s2));

s1==s2
比较的不是起指向的对象的内容是否相等,而是s1和s2的引用是否相同,显然是不同的,你实例话了2个对象~其内容相同,但在内存中存储的位置是不同的,所以为false.
String s1="aa"
String s2="aa"
System.out.println("s1==s2"+(s1==s2));
System.out.println("s1.equals(s2)"+s1.equals(s2));
和上面则相反。你这样写~使s1指向内存内容为“aa”这个对象, 也就是把aa这个对象的引用赋值给s1,String s2="aa",也把相同的引用赋值给s2,所以s1==s2,输出的为true.不知道我说明白没有,我也是初学!我是这么理解的!

3.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: zxasqw
Posted on: 2005-12-11 22:21

hamlet
说的基本是正确的,但是一般==都是比较基本类型,而对象是用equals的,利用的是hashcode

4.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: andykid
Posted on: 2005-12-12 22:58

String s1="aa";创建了几个String对象?String s2=new String("aa");又创建了几个String对象?
个人理解, String s1="aa"是一个陷阱,它有可能并没有创建String对象,因为String s1="aa"这样的形式是在栈中分配,如果在栈中有另一个地址存有"aa",则String s1="aa"这句只是创建了一个String 类型的引用s1,指向一个存有aa的地址。反之则创建一个对象存放"aa",并将引用给s1;
而String s2=new String("aa"),则肯定会在堆中创建一个存放"aa"的对象。而不管在堆中是否另有地址有"aa" 这个值
只是个人理解

5.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: andykid
Posted on: 2005-12-12 23:03

String s1="aa" ;String s2="aa" 创建了几个String对象?
从上下文来联系,是创建了一个String 对象,
s1创建了后,String s2="aa",jvm发现在栈中已经有一个地址存放"aa",就直接把这个地址的引用告诉s2,而不会再创建对象了
String s1=new String("aa"); String s2=new String("aa");
这种是在堆中分配内存,创建了两个对象。

6.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: andykid
Posted on: 2005-12-12 23:11

String s1=new String("aa");
String s2=new String("aa");
System.out.println("s1==s2"+(s1==s2));
按jdk5.0的官方解释,==是比较引用。
String s1=new String("aa");
String s2=new String("aa");如这样的语句是在堆中分配,不管在堆中有没有相同的数据,只有new了,都会产生对象,s1和s2的引用不同,所以结果为false

String s1="aa";
String s2="aa";这样的语句是在栈中分配,当jvm执行String s1="aa"时产生了存放"aa"的地址空间并把引用给了s1,在执行String s2="aa"时发现在栈中已经有了一个地址空间存放"aa",就直接把这个引用给了s2,所以s1和s2的引用是一样的,结果为true
说了这么多也不知道对不对,还得请高手指正,这也是偶个人的理解哈

7.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: scarecrow
Posted on: 2005-12-14 16:02

>>String s2="aa";这样的语句是在栈中分配,当jvm执行String s1="aa"时产生了存放"aa"的地址空间并把引用给了s1,在执行String s2="aa"时发现在栈中已经有了一个地址空间存放"aa",就直接把这个引用给了s2,所以s1和s2的引用是一样的,结果为true

这样的解释欠妥当
String s2="aa" .这个句话并没有在栈中分配任何空间 。"aa"是符号常量自然有其符号地址,String s2 ="aa"; String s1="aa"; 定义的意思是 s1和s2指向相同的符号地址。既然 s1和s2指向相同的地方 s1==s2当然是true

8.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: andykid
Posted on: 2005-12-14 23:52

这样的解释欠妥当
String s2="aa" .这个句话并没有在栈中分配任何空间 。
引自关于java栈与堆的思考 作者 zdmilan
关于String str = "abc"的内部工作。Java内部将此语句转化为以下几个步骤:
  (1)先定义一个名为str的对String类的对象引用变量:String str;
  (2)在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象o,并将o 的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为"abc"的地址,则查找对象o,并返回o的地址。
  (3)将str指向对象o的地址。
  值得注意的是,一般String类中字符串值都是直接存值的。但像String str = "abc";这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!

引用一下,讨论一下对错,以及对String的理解

9.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: scarecrow
Posted on: 2005-12-15 11:04

>>先定义一个名为str的对String类的对象引用变量:String str;
这句话问题不大,就是在栈中分配一个指向String的指针变量str(和定义一个名为str的对String类的对象引用变量语义相同)

>>在栈中查找有没有存放值为"abc"的地址,
栈是存放变量的,并不能存放什么地址。所谓存放地址就是在栈中存放的指针变量用来存放的地址;

>>如果没有,则开辟一个存放字面值为"abc"的地址.
已经有一个str引用变量了,为何还要再开辟一个存放"abc"地址的存储空间?直接把str指向"abc"的地址(和str作为常量字符串的引用是一样的语义)
>> 接着创建一个新的String类的对象o
这个对象如何创建?据我所知JAVA中所有的对象实例创建都是在堆中,否则只是创建该对象的引用变量,既然有了str的引用再创建一个又有何用?

>>并将o 的字符串值指向这个地址

字符串值指向地址?听起来很矛盾啊。

>>将str指向对象o的地址。
作者似乎也明白str可以是指向地址。直接指向符合常量"abc"的地址不就ok了。为何非得弄出来个o阿。唯一的解释是"abc"不是String类型不能直接引用"abc",虚拟机内部需要通过 o= new String("abc"); 创建一个String对象的实例然后再通过str引用此实例。

至于我的结论我是根据我对C语言的理解和指针的概念得出来的,我JAVA的对象引用应该何C语言的指针类似. 。我不能确信我的结论是否正确。但是感觉作者对其的解释的很混沌不清。

10.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: andykid
Posted on: 2005-12-16 00:01

。"aa"是符号常量自然有其符号地址
能否具体解释下"aa"存放在什么地方呢?
偶的理解是aa存放在栈中。

11.Re:创建String对象的问题 [Re: andykid] Copy to clipboard
Posted by: scarecrow
Posted on: 2005-12-16 10:28

andykid wrote:
。"aa"是符号常量自然有其符号地址
能否具体解释下"aa"存放在什么地方呢?
偶的理解是aa存放在栈中。


对JAVA虚拟机的内存模型不同清楚我就拿C/C++说明吧(我认为两者应该差别不大)
在c/c++里 内存被分为5个区域 堆、栈、自由存储区、全局/静态存储区和常量存储区。常量属于符号地址在编译的时候常量会被分配放置在常量存储区域也就是说常量地址是静态的一旦编译以后他的地址就是固定不变的。而堆栈变量的存储区域是在运行的时候在栈中动态分配的。

12.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: Jcat
Posted on: 2005-12-18 20:01

equals和compareTo的“比较机制”是相同的

equals()
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
从最后一句话可以看出,equals 比较的是“内容”

compareTo()
Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argument string. The result is a negative integer if this String object lexicographically precedes the argument string. The result is a positive integer if this String object lexicographically follows the argument string. The result is zero if the strings are equal; compareTo returns 0 exactly when the equals(Object) method would return true.

13.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: Jcat
Posted on: 2005-12-18 20:10

equals( )出生时与==是等价的

Object类中对equals的定义
The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).
可以理解为它们都是在比较“引用”

14.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: Jcat
Posted on: 2005-12-18 20:35

被重写的equals和==的不同之处
The equality operator can be used to compare two object variables of the same type. In this case, the result of the comparison is true only if both variables refer to the same object. Here is a demonstration:
m1 = new Mammal();
m2 = new Mammal();
boolean b1 = m1 == m2; //b1 is false

m1 = m2;
boolean b2 = m1 == m2; //b2 is true


The result of the first equality test is false because m1 and m2 refer to different objects (even though they are of the same type). The second comparison is true because both variables now represent the same object.

Note: Most of the time, however, the equals() method in the Object class is used instead of the comparison operator. The comparing class must be subclassed from Object before objects of the comparing class can be compared using equals().

15.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: andykid
Posted on: 2006-01-14 15:41

不好意思,接着讨论,上次对string的理解有点误解,scarecrow兄说的有道理,现在偶已经理解
String s1="aa";
String s2="aa";
s1==s2 true的道理。
偶想问一下象如下的这种情况
String s1="JA";
String s2="VA";
String s3=s1+s1;
s3=="JAVA" true or false?
s3的内容是放在堆中还是和s1或s2所指内容一样放在一个文字池中呢?

16.Re:创建String对象的问题 [Re: andykid] Copy to clipboard
Posted by: zcjl
Posted on: 2006-01-14 16:16

false
s3是在堆中的
可以使用s3.intern()获得(相同值在)栈中的对象
所以s3.intern()=="JAVA"为true

17.Re:创建String对象的问题 [Re: javahum] Copy to clipboard
Posted by: andykid
Posted on: 2006-01-14 17:10

谢谢zcjl!总算理了一点头绪出来


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923