请教String怪问题

dgsrest 2003-08-12 02:05:16
我初始化
String s1="abc";
String s2="abc";
String s3=new String("abc");
String s4=new String("abc");
我们知道"=="是引用的对比
我用程序测试 s1==s2 true //为什么会是true呢
s1=="abc" true //?
s3==s4 false
这两种初始化有什么本质上的区别吗?请指教!谢谢!

...全文
27 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
polyhill 2003-08-14
  • 打赏
  • 举报
回复
顺便说一句上述方法查看到的内存占用情况并不是真实100000000字符串对象占用的内存大小,因为垃圾回收机制会回收先前构件而不再需要的字符串对象。如果想通过采用数组方式来保存这些对象实现查看到真实的内存占用情况,你将会的到out of memory的错误信息
polyhill 2003-08-14
  • 打赏
  • 举报
回复
效率将低得多,需要76560ms

这是因为首先要通过String.valueOf(i)构建字符串"i"对象,然后执行+操作,再构建new String("abci")对象,这样造成效率低下
zoominet 2003-08-14
  • 打赏
  • 举报
回复
楼上的解释很透彻。
我有一个问题,楼上的用引用是针对同一个“abc”,如果引用的是不同
对象呢?比如:
for(int i=0;i<100000000;i++){
String s1 = "abc" + i;
}
这样的效率怎样?
polyhill 2003-08-14
  • 打赏
  • 举报
回复
如果我们声明String str = new String(“abc”);时jvm将构造一个新的字符串对象,其值为“abc”;如果我们声明String str = “abc”;时jvm将首先判断在堆中是否已经存在“abc”对象,如果存在那么则将已存在的“abc”对象的引用赋给str,否则将构造“abc”对象,然后再将“abc”对象的引用赋给str。
上述情况将带来一推论:程序中使用多次如String str = “abc”;这样的赋值方式并不会新增多个字符串对象,而只是对一个字符串对象的不同引用。
我们采用如下方式证明上述描述:
1、String s1=“abc”;
String s2=“abc”;
System.out.println(s1= =s2);//print true

String s3=new String(“abc”);
String s4=new String(“abc”);
System.out.println(s3= =s4);//print false
上述证明了这两种情况的赋值和构建对象的方式是不同的。
2、我们下面通过显示两种情况性能的差异来进一步证明String s2=“abc”;的方式是不构建对象的(我们知道构造对象效率将较低,并且通过构造对象内存的占用率也要相应提高,下面数据是在本机(P42.4G MEM1G)测试的结果)。
long time = System.currentTimeMillis();
for(int i=0;i<100000000;i++){
String s1 = new String("abc");
}
System.out.println(System.currentTimeMillis() - time);//print 6000ms,
//内存占用5364
while(true){}//为了查看内存占用率较方便

long time = System.currentTimeMillis();
for(int i=0;i<100000000;i++){
String s1 = "abc";
}
System.out.println(System.currentTimeMillis() - time);//print 300ms,
//内存占用4820
while(true){}//为了查看内存占用率较方便
dgsrest 2003-08-14
  • 打赏
  • 举报
回复
java中没有String这种基本类型的,
我知道s3,s4是指向对象的引用,所以s3!=s4,

String s1="abc";
String s2="abc";
s1,s2是引用吗?是指向同一对象的引用?每一个"abc"都是一个独立的对象吧?
请指教,谢谢!
feiyuegaoshan 2003-08-14
  • 打赏
  • 举报
回复
经典老问题了:)依次解释如下:
String s1="abc";
String s2="abc";
jvm对以上两个对象做了优化,内存里是分配的同一个地址。
String s3=new String("abc");
String s4=new String("abc");
jvm为new 分配不同的地址。

所以,产生了你的“疑惑”。
Jumperr 2003-08-14
  • 打赏
  • 举报
回复
收藏收藏
shine333 2003-08-14
  • 打赏
  • 举报
回复
代码中有"......"的地方,编译的时候,都将所有String s = "....."的指向统一个地方,以作优化
formalin 2003-08-14
  • 打赏
  • 举报
回复
对于s1==s2,s3!=s4,确实如polyhill(hill)所说
而s1=="abc",确实是重载的缘故。
tele 2003-08-14
  • 打赏
  • 举报
回复
看过java认证考试的书,polyhill(hill)说的是正确的
zez 2003-08-14
  • 打赏
  • 举报
回复
polyhill(hill)
的解释是正解 ...

------------------------------------------------------
我们还年轻牛奶会有的奶牛也会有的
可天天在 csdn 混这些会有吗 ??
formalin 2003-08-14
  • 打赏
  • 举报
回复
抱歉,查了一下,不是String类做的重载,而是java.lang.Object,比较常量时比的是所有属性,比较对象时比的是引用。
David_7678 2003-08-14
  • 打赏
  • 举报
回复
不错,对!
formalin 2003-08-14
  • 打赏
  • 举报
回复
其实是运算符重载

对象比较时,比的是引用,所以s3==s4 false

String类重载了运算符:==。与"abc"(String类常量)比较时,比的是value,而不是对象引用,所以s1=="abc" true
HenryY 2003-08-14
  • 打赏
  • 举报
回复
很透彻
alemjann 2003-08-14
  • 打赏
  • 举报
回复
好贴子!丁!
lotofu 2003-08-14
  • 打赏
  • 举报
回复
s1, s2 是常量,常量只分配一个空间。
而s3,s3是新new的变量,各分配一个空间!!!明白?
teaky2002 2003-08-12
  • 打赏
  • 举报
回复
s1,s2,s3,s4都是对象,情况跟老驴说的一样。
ringphone 2003-08-12
  • 打赏
  • 举报
回复
s3,s4其实说起来是指针,所以s3!=s4
whyxx 2003-08-12
  • 打赏
  • 举报
回复
在jdk1.4中,好像已经对String的"=="做过处理,使得String类的==和int,long等类型的==具有相同的功能,也就是说在jdk1.4中,String类的==和equals()应该是一样的结果了
加载更多回复(12)

62,615

社区成员

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

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