请教关于string的问题?
小弟在学习中看到一代码,测试如下:
public class test
{
public static void main(String []args)
{
String hello="hello";
String hel="hel";
String lo="lo";
System.out.println(hello=="hel"+"lo");//文字字符传常量
System.out.println(hello==hel+lo);//字符传变量
}
}
结果:
true;
false;
问题:请教大家关于Sting对象的创造过程,在那里存放?然后用一个标示符来引用他;
那么第一个句子为什么是true?第二个flase?
我看了java language special有关于liteal string的一端:
我读了读,不知道对不对,还有不懂的地方,多多请教。
Strings computed by constant expressions are computed at compile time and then treated as if they were literals.在编译时使用常量表达来计算的字符串将把他看为文字常量
Strings computed at run time are newly created and therefore distinct.在运行时刻的字符串计算被重新建立,因此和编译时刻的不同
The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents ?
问题点数:30、回复次数:13Top
1 楼xitianjile(空想社會主義)回复于 2005-02-03 12:57:19 得分 0
你的研究好细啊.Top
2 楼DDLLRR(自才)回复于 2005-02-03 17:38:25 得分 0
对了,看了关于一些贴之后,我觉得我要知道的是:
1 string对象创造的过程是怎么回事?如果是string x ="aa";这样,是使用引用一个string对象,然后在那里(常量池??我不知道)寻找是否有相同内容的string对象,有,则传一个引用给所需引用的对象,没有,自动创造一个,然后返回地址给此引用变量;是这样吗?可是对于"hel"+"lo"来说是怎么产生"hello"的呢?有没有用到stringbuffer?看了JDK的stringbuffer.tostring()
public String toString() {
return new String(this);//返回了一个新的string对象
}
对于"hel"+"lo"和hel+lo有什么区别??
谢谢大家,谢谢高手,新年快乐!!!
敬!!!!!!!!!!!!!Top
3 楼mu_x(阿木)回复于 2005-02-03 17:47:25 得分 5
前者是常量相联接,编译器就能完成,后者是两个字符串变量相联接需要到运行时才能确定其中的内容。Top
4 楼lxleaves(飘泊的叶子)回复于 2005-02-03 17:56:04 得分 10
System.out.println(hello=="hel"+"lo");//文字字符传常量
这个地方你反编译就看到实际上是
System.out.println(hello=="hello");Top
5 楼whunlay(就是我)回复于 2005-02-03 18:24:24 得分 0
我把你第二个比较语句改了一下:
System.out.println(hello.equals(hel.concat(lo)));
结果就为true了。
Top
6 楼xzhm1007(xzhm)回复于 2005-02-03 18:27:37 得分 0
你的研究够仔细啊,我楼上的是正确的!Top
7 楼lxleaves(飘泊的叶子)回复于 2005-02-03 18:39:47 得分 0
楼上和楼上的楼上仔细看楼主的问题Top
8 楼lxleaves(飘泊的叶子)回复于 2005-02-03 18:42:11 得分 0
附上楼主程序的反编译结果
// Decompiled by DJ v3.7.7.81 Copyright 2004 Atanas Neshkov Date: 2005-2-3 18:41:05
// Home Page : http://members.fortunecity.com/neshkov/dj.html - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: test.java
import java.io.PrintStream;
public class test
{
public test()
{
}
public static void main(String args[])
{
String s = "hello";
String s1 = "hel";
String s2 = "lo";
System.out.println(s == "hello");
System.out.println(s == (new StringBuilder()).append(s1).append(s2).toString());
}
}Top
9 楼sbgphl(十八哥)回复于 2005-02-03 19:25:37 得分 0
upTop
10 楼bxh2dai(希望明天会有些改变)回复于 2005-02-03 20:22:48 得分 5
System.out.println(hello=="hel"+"lo");/ 为TRUE的原因是,因为hello与"hel"+"lo"是同一个对象
System.out.println(hello==hel+lo);//为FALSE的原因是因为hello与hel+lo虽然值一样,但是不是同一个对象,也就是说指向的内存地址不在同一个空间Top
11 楼zj_ok(zj_ok)回复于 2005-02-03 20:49:29 得分 0
有关对象的比较建议都用equals,否则很容易出错
上面的问题不同的编译器实现有可能不同,会出不同的结果,就没有必要死钻牛角尖了Top
12 楼apollo333()回复于 2005-02-04 03:01:01 得分 10
同意“bxh2dai(希望明天会有些改变) ”的观点。
另外,
String hello="hello";
String hel="hel";
String lo="lo";
String h = new String("hello");
System.out.println(hello=="hel"+"lo");//文字字符传常量
System.out.println(hello==hel+lo);//字符传变量
System.out.println(hello=="hello");
System.out.println(h=="hello");
结果就是
true
false
true
false
因为 String hello="hello";这个JAVA在内存里创建了“hello"对象。hello这个变量指向这个对象。
因为是LITERAL STRING。所以"hel"+"lo"生成时就是已经存在的"hello"对象。
String h = new String("hello");在JAVA API里解释说是新生成了2个STRING 对象。
一个是遇到"hello"这个LITERAL STRING时,一个是在NEW 的时候。
最后说一下楼上的观点。不管什么编译器,只要是JAVA的,就不可能不同结果。对于对象,不是基本类型 ,==是判断是否引用同一个对象。EQUALS()判断是否值相同。Top
13 楼DDLLRR(自才)回复于 2005-02-05 21:07:59 得分 0
首先谢谢各位朋友的帮助和支持,祝大家新年快乐,身体健康!
今天看了大家的讨论收益非浅!
总结一下:
啊木说的对前者是常量能在编译时刻就确定的,所以第一个式子是true;
而第2个则是运行时才能确定的,另外谈一下:那么关于string(常量对象)是不是涉及有对象改变的情况就自动调用Stingbuffer在产生运算结果后使用tostring来返回给一个string对象
public String toString() {
return new String(this);
}
正如“漂泊的叶子”所做的反编译,看到的一些情况
System.out.println(s == (new StringBuilder()).append(s1).append(s2).toString());
Top




