关于JAVA对象的假想

stephenzhou1234 2006-04-11 10:19:28
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 ????
...全文
426 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
iamlain 2006-04-12
  • 打赏
  • 举报
回复
== 是内存地址比较
Stack 里面的东西是共享的
String s1 = "aa";
产生了一个 STRING OBJECT 在HEAP里面 他的引用在STACK里面 "AA" 内容却在STACK里面
S1 在STACK里的引用指向HEAP里面的STRING对象 HEAP里的对象把内容放在了STACK里
做鸡真好吃 2006-04-12
  • 打赏
  • 举报
回复
Mark~
hemiao_1993 2006-04-12
  • 打赏
  • 举报
回复
建议你好好看看关于Java是怎样处理在栈和堆中存放数据的。

java之所以把primitive的数据存储放在栈中是出于速度考虑。
而其他的Object对象呢全部在堆中存储。
--------------------
我只是说对象绝对不会存储在栈中, 好像没有说其他的吧.
MagicianLiu 2006-04-12
  • 打赏
  • 举报
回复
学习
grant999 2006-04-11
  • 打赏
  • 举报
回复
关于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 str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true

注意,我们这里并不用str1.equals(str2);的方式,因为这将比较两个字符串的值是否相等。==号,根据JDK的说明,只有在两个引用都指向了同一个对象时才返回真值。而我们在这里要看的是,str1与str2是否都指向了同一个对象。
结果说明,JVM创建了两个引用str1和str2,但只创建了一个对象,而且两个引用都指向了这个对象。

我们再来更进一步,将以上代码改成:

String str1 = "abc";
String str2 = "abc";
str1 = "bcd";
System.out.println(str1 + "," + str2); //bcd, abc
System.out.println(str1==str2); //false

这就是说,赋值的变化导致了类对象引用的变化,str1指向了另外一个新对象!而str2仍旧指向原来的对象。上例中,当我们将str1的值改为"bcd"时,JVM发现在栈中没有存放该值的地址,便开辟了这个地址,并创建了一个新的对象,其字符串的值指向这个地址。
事实上,String类被设计成为不可改变(immutable)的类。如果你要改变其值,可以,但JVM在运行时根据新值悄悄创建了一个新对象,然后将这个对象的地址返回给原来类的引用。这个创建过程虽说是完全自动进行的,但它毕竟占用了更多的时间。在对时间要求比较敏感的环境中,会带有一定的不良影响。

再修改原来代码:

String str1 = "abc";
String str2 = "abc";

str1 = "bcd";

String str3 = str1;
System.out.println(str3); //bcd

String str4 = "bcd";
System.out.println(str1 == str4); //true

str3 这个对象的引用直接指向str1所指向的对象(注意,str3并没有创建新对象)。当str1改完其值后,再创建一个String的引用str4,并指向因str1修改值而创建的新的对象。可以发现,这回str4也没有创建新的对象,从而再次实现栈中数据的共享。

我们再接着看以下的代码。

String str1 = new String("abc");
String str2 = "abc";
System.out.println(str1==str2); //false

创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象。

String str1 = "abc";
String str2 = new String("abc");
System.out.println(str1==str2); //false

创建了两个引用。创建了两个对象。两个引用分别指向不同的两个对象
angel_bear 2006-04-11
  • 打赏
  • 举报
回复
学习
Camelh 2006-04-11
  • 打赏
  • 举报
回复
楼上的正解
ysycrazy 2006-04-11
  • 打赏
  • 举报
回复
question1:
『问』
1.String s1="aa";创建了几个String对象?
『解答』
只创建一个String对象,并且引用s1和它所指的对象本身都存储在栈(stack)中。
『问』
2.String s2=new String("aa");又创建了几个String对象?两句话有什么区别?
『解答』
创建了一个Sting对象,并且引用s2存储在栈(stack)中,而它所指的对象本身存储在

堆(heap)中。

question2:
『问』
1.String s1="aa" ;String s2="aa" 创建了几个String对象?String
『答』
创建了一个对象,栈中的引用s1和s2都指向栈中的同一个对象。
『问』
2.s1=new String("aa"); String s2=new String("aa");又创建了几个对象??
『答』
创建了两对象,栈中的引用s1和s2分别指向堆中不同的对象。
jobs002 2006-04-11
  • 打赏
  • 举报
回复
木星
hemiao_1993 2006-04-11
  • 打赏
  • 举报
回复
火星.
stephenzhou1234 2006-04-11
  • 打赏
  • 举报
回复
而且 这句话产生了一个STRING OBJECT
String str2 = "abc";

肯定STRING OBJECT在HEAP里面 那建立了对象为什么会出现在STACK 而不是HEAP
//String is object
stephenzhou1234 2006-04-11
  • 打赏
  • 举报
回复
STACK数据是可以共享的这个概念很模糊
因为OBJECT 的REFERNCE 也在STACK里面
如果每次产生一个东西都需要去STACK里面查询一次 效率上真的不怕吗
怀疑中 ~~~

在Java Doc有这段对于Stack存储区的描述
stack storage object references--java objects themselves are not placed on the stack

String is object and still a primitive types
so if you use // new String("aa"); is a String Object in heap
if you use //String s1="aa"; "aa" is in stack not in heap
不过这有点矛盾 后者至少 会产生一个对象
前者是产生了两个对象

郁闷ING
ysycrazy 2006-04-11
  • 打赏
  • 举报
回复
To:stephenzhou1234(stephen):
注String 是很奇怪的东西

String str1 = "abc";
在栈中分配了引用空间str1,并且在栈中寻找有没有存储值为"abc"的空间,如果有则把该空间的首地址赋值给str1,如果没有则会产生一块新的空间用来存储"abc",并把该空间的首地址赋值给str1.
String str2 = "abc";
同上...
System.out.println(str1 == str2); //true
所以str1和str2存储的地址是相同的,所以打印值应该为true

只能是String成立如果换Integer则不成立

Integer i1 = Integer.valueOf("1");
它在栈中给引用i1 分配了一个空间,然后在堆中生成了一个对象并且把它的首地址赋值给i1,所以我们就可以用栈中的引用i1来操作堆中对应的对象了。
Integer i2 = Integer.valueOf("1");
它在栈中给引用i2 分配了一个空间,然后在堆中生成了一个对象并且把它的首地址赋值给i2,所以我们就可以用栈中的引用i2来操作堆中对应的对象了。

System.out.println(i1 == i2); //false 两个不同的内存地址
因为引用i1和i2所指不同的对象,所以他们的值也不相同。


注:栈中的数据是可以共享的,而堆中的数据是不可以共享的。

int a = 3;
int b = 3;
分析:
其实在栈中存储3这个值的这个内存块只有一个。a和b 是共享的。a和b中实际是存储3这个内存块的地址。两个引用存储的是同一个地址,无论如何a始终等于b。
ysycrazy 2006-04-11
  • 打赏
  • 举报
回复
to:hemiao_1993(冷血动物)
『问』
1.String s1="aa";创建了几个String对象?
『解答』
只创建一个String对象,并且引用s1和它所指的对象本身都存储在栈(stack)中。
-------------------------
对象存储在栈中, 长见识了!

建议你好好看看关于Java是怎样处理在栈和堆中存放数据的。

java之所以把primitive的数据存储放在栈中是出于速度考虑。
而其他的Object对象呢全部在堆中存储。
stephenzhou1234 2006-04-11
  • 打赏
  • 举报
回复
注String 是很奇怪的东西

String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2); //true

只能是String成立如果换Integer则不成立

Integer i1 = Integer.valueOf("1");
Integer i2 = Integer.valueOf("1");
System.out.println(i1 == i2); //false 两个不同的内存地址
stephenzhou1234 2006-04-11
  • 打赏
  • 举报
回复
对象不能存在STACK里面
只能存在于HEAP
STACK里只能是对象引用的内存地址
内存地址是HEAP区上的起始地址加上偏移量 HEAP里是2进制形式的存放
stephenzhou1234 2006-04-11
  • 打赏
  • 举报
回复
1.String s1="aa";创建了几个String对象?
『解答』
只创建一个String对象,并且s1的引用在(stack)中 但是 "aa"在heap内存里面
『问』
2.String s2=new String("aa");又创建了几个String对象?两句话有什么区别?
『解答』
创建了两个Sting对象,并且s2引用存储在栈(stack)中,s2对象存在heap里面
s2指向了 new 的一个临时String 对象而 这个临时的对象指向了heap里面"aa"的存放地址


String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2); //true
说明是地址的比较 在heap上分配"abc"空间之前 查看stack里是否有"abc"的引用 如果有
直接返回(感觉如果这样会造成效率问题)

String str1 = "abc";
String str2 = "abcd";
str2 = str2.substring(1,3); //str2 value "abc"
System.out.println(str1 == str2); //false

总结 == 始终是比较引用地址是否相等
值的比较只能是equle()方法


hemiao_1993 2006-04-11
  • 打赏
  • 举报
回复
2.String s2=new String("aa");又创建了几个String对象?两句话有什么区别?
『解答』
创建了一个Sting对象,并且引用s2存储在栈(stack)中,而它所指的对象本身存储在

堆(heap)中。
---------------------------
这个回答也不对, 唉!
hemiao_1993 2006-04-11
  • 打赏
  • 举报
回复
『问』
1.String s1="aa";创建了几个String对象?
『解答』
只创建一个String对象,并且引用s1和它所指的对象本身都存储在栈(stack)中。
-------------------------
对象存储在栈中, 长见识了!

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧