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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 周兴中 中级黑马   /  2012-6-23 01:10  /  2255 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 周兴中 于 2012-6-24 21:31 编辑

String s1="abc";
String s2="abc";
以上两句话表示s1和s2都指向了堆内存中的"abc"
因为"=="比较的是对象的地址值,所以 s1==s2 为true

那为什么
String s3=new String("java");
s3=="java" 的结果却为false,难道是这句话先是在堆内存中又创建了一个String对象,其值为java吗?

               
听完你们回答貌似更模糊了.
                String s3 = new String("java");  // 在堆内存开辟空间存储String类型的 java ,s3则在栈内存中指向 java ,既 s3的值为 java 这个对象在内存中的地址.
                System.out.println(s3 == "java"); //返回false,为什么?   这句话不是表示 s3所指向的java的地址 是否等于 "java"对象的地址?  "java"这个字符串在内存中我只new了一次,不是应该相等吗
               
                String s1="abc";               
                System.out.println(s1=="abc");//返回true,为什么?

8 个回复

倒序浏览
恭喜你回答正确

当String s3=new String("java");时,系统会开辟新的存储空间。所以s3==“java”是比较的不同的内存地址,肯定false了
回复 使用道具 举报
        String str1="abc";
        String str2="abc";
        String str3="ab"+"c";
        String str4=new String(str2);



1、编译的时候,"abc"被存储在常量池中,str1和str2的引用都是指向常量池中的"abc"。所以str1和str2引用是相同的.
2、 编译器会做出优化,先把字符串拼接,再在常量池中查找这个字符串是否存在,如果存在,则让变量直接引用该字符串。所以str1和str3引用也是相同的。
3、str4的对象不是显式赋值的,编译器会在堆中重新分配一个区域来存储它的对象数据。所以str1和str4的引用是不一样的
回复 使用道具 举报
重点理解 String s1 = "abc";  和String s2 = new String("abc");的区别是:

首先 String s1 = "abc","abc"就表示一个字符串对象。而s1是"abc"对象的地址,也叫做"abc"对象的引用。 此处s1在内存中只有一个对象,即为“abc”,该语句只是声明一个指向String类型对象“abc”的引用s1,这样定义只是声明一个可以指向String类型的引用变量而已。

而String s2 = new String("abc");这个语句创建了两个对象,一个是字符串对象,一个是指向这个字符串的应用对象。
它创建字符串“abc”的一般步骤是:先在栈中开辟空间存储s2 --> 在堆中开辟空间存放新疆的Sting类对象“abc” --> 将引用s2指向堆中新建的String类对象“abc”;  --> s2所指代的对象地址为堆中地址,而String常量"abc"地址在字符串池中,所以输出为false;




回复 使用道具 举报
    String为引用数据类型,这种数据类型在声明变量时会在堆中开辟空间用来保存变量的值,而在栈中保存所开辟空间的首地址!所以在这个地方s1,s2和s3都是指向保存变量的地址值!(1)s2=“abc”为一个对象,而new的时候又产生了一个对象;(2)s1=s3,是把s1的地址值赋给了s3,

   用“==”来比较的是他们具体的值,因此返回值为true。而用equals()方法来比较的话就是比较s1,s2,s3所指向的对象的值!例如s1.equals(s2),此时返回的是true!
回复 使用道具 举报
楼主说的没错,String s3=new String(“java”);这句话就是在堆内存中开辟了一个新的对象名为s3值为java
而你用s3==“java” 后边的“java”是在堆内存中找到的名为java值也为java的内存所以你用s3对象的地址和java对象的地址相比较,肯定会是false喽
而下边写的 String s1=“abc”;是将堆内存中找到“abc”并将栈内存中的s1指向“abc”类似于c的指针,也就是这时候s1的内存地址就是“abc”的地址所以你这时候用s1==“abc”这是true
-------------
求分
回复 使用道具 举报
因为String s3=new String("java"); s3=="java"这两个存储的位置是不相同的。用new来创建的存储在了堆中,而s3=“java”存储在了“堆栈”中。随意他们的地址肯定是不想同的。
java中凡是new出来的对象,都是分配在堆中的,而基本类型和直接赋值的一般存储在堆栈中。
有关java中对象的存储你可以看一下我的这个blog,希望能有助于你的理解
http://www.rolfwang.com/technology/259.html
回复 使用道具 举报
String s3=new String("java")系统开辟新的存储空间; 用new来创建的存储在了堆中,而s3=“java”存储在了“堆栈”中;与s3=="java"这两个存储的位置是不相同的。
回复 使用道具 举报
……
String s3=new String("java");
s3=="java"
……

// s3 是一个引用类型,存储的是地址值,指向在堆内存中存放的“java”
// "java"是一个值, 所以两者不相等。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马