A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 陈磊 黑马帝   /  2011-8-3 22:09  /  2229 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

[code=java]class Other {
        static String hello = "Hello";
}

public class HelloWorld {
        public static void main(String[] args) {
                String hello = "Hello", lo = "lo";

                System.out.println((hello == "Hello") + " ");
                System.out.println((Other.hello == hello) + " ");
                System.out.println((Other.hello == hello) + " ");
                System.out.println((hello == ("Hel" + "lo")) + " ");
                System.out.println((hello == ("Hel" + lo)) + " ");
                System.out.println(hello == ("Hel" + lo).intern());
        }
}[/code]我想问的是 System.out.print((hello == ("Hel"+lo)) + " "); 这一行的结果为什么是false??
想半天想不明白

评分

参与人数 1技术分 +1 收起 理由
admin + 1 新人份上给分了

查看全部评分

7 个回复

倒序浏览
黑马网友  发表于 2011-8-3 22:18:23
沙发
hello是一个String对象,在内存栈中存放了一个地址引用,实际的“Hello”放在内存堆中,而你的“Hel”+lo
是Hel这个字符串对象加上lo这个字符串对象,后者是两个String对象,在内存栈中有两个引用,在堆中有两个实际的数据存储,前者是一个对象,后者是两个对象,用==比较当然是folse啦

评分

参与人数 1技术分 +1 收起 理由
admin + 1 给分了

查看全部评分

回复 使用道具 举报
楼上的童鞋,比较的是一个对象,不是两个对象!我查了不少资料,所以说呢,现在我对String还是比较了解的。

hello 发生在编译时,被放在字符串池String pool中,栈内存里,也就是说,hello在编译时已经知道它的值是"hello"了
"Hel" + lo 发生在运行时,新生成的一个字符串,编译时,"Hel" + lo的值还不知道,因为这个表达式有引用参加运算,算是动态的字符串,只有在运行时才产生它的对象,这时才知道它的真正地址。你想想运行时产生的地址和编译时产生的地址会相同吗?

下面是字符串intern方法的api解释和其源码,看懂了你就知道方法返回的是字符串在字符串池的栈内存的引用。
而同一时间,字面值相同的字符串在字符串池中只有一个栈内存地址的引用,因为如果相同的字符串想加入到字符串池的时候,返回的是字符串池里面那个字面值相同的字符串的内存地址。所以"hello"==hello,("hel"+lo).intern()==hello,返回的都是true。[code=java]/* <p>
     * When the intern method is invoked, if the pool already contains a
     * string equal to this <code>String</code> object as determined by
     * the {@link #equals(Object)} method, then the string from the pool is
     * returned. Otherwise, this <code>String</code> object is added to the
     * pool and a reference to this <code>String</code> object is returned.
     * <p>
* @return  a string that has the same contents as this string, but is
     *          guaranteed to be from a pool of unique strings.
     */

public native String intern();[/code]我在帖子http://bbs.itheima.com/thread-377-1-1.html中有较详细的回答,你可以参考。
[ 本帖最后由 覃俊瑞 于 2011-08-03  23:08 编辑 ]

评分

参与人数 1技术分 +2 收起 理由
admin + 2 这就是学术的态度,覃俊具备毕业拿8k的潜质

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-8-3 23:15:16
板凳
首先  看着你定义的那些变量 我脑袋大了:L
==符号是判断两个对象句柄是否相等(也就是两个句柄是否指向同一个对象)
hello 是指向常量池中的"Hello" 的引用
从下面的一行[code=java] System.out.println(hello == ("Hel" + lo).intern());[/code]可以判断他们为false的原因是"Hel" + lo运算后的Hello不在常量池中。
"Hel" + lo返回的是一个指向值为"Hello"的StringBuffer对象的引用。
所以两个引用不等。false
这是我自己的理解!仅供参考……

评分

参与人数 1技术分 +2 收起 理由
admin + 2

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-8-3 23:28:42
报纸
:loveliness: admin老师您过奖啦,我不过是多百度一下。
回复 使用道具 举报
黑马网友  发表于 2011-8-4 12:27:59
地板
不是说打印的时候 会有个自动toString么 是不是因为 这个 “hel” +lo 字符串加引用 没法 toString 了
回复 使用道具 举报

回复 地板 的帖子

System.out.println(("Hel" + lo).toString());//Hello

“hel” +lo -----运行时,会创建一个新的字符串对象,再返回一个地址的引用,当打印这个引用的时候,该引用会调用父类String的toString()方法。
回复 使用道具 举报

回复 楼主 的帖子

:handshake 原因:String类型是不可变的。
解析:hello和lo是两个不同的对象,(“Hel”+lo)是新创建的字符串类型对象,
这里的三个对象是不同的,hello == ("Hel"+lo)   当然要false了。
[ 本帖最后由 fenglh 于 2011-08-06  13:17 编辑 ]

评分

参与人数 1技术分 +2 收起 理由
老罗 + 2 不仅要回答,学习中遇到问题要提出来哦。

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马