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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© sunalong 中级黑马   /  2013-7-24 22:06  /  1592 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨兴庭 于 2013-7-25 11:31 编辑
  1. public class StringDemo {
  2.         public static void main(String[] args){
  3.                 String s1 = "abc";
  4.                 String s2 = new String("abc");
  5.                 /*s1与s2的区别:
  6.                  * s1在内存中有一个对象
  7. <p>          * s2在内存中有两个对象//这话是毕老师讲的……</p><p>
  8. </p>                 * 疑://有两个对象?哪两个,s2是一个引用型变量,它指向对象的地址,
  9.                  * 但有两个对象,它指向哪个对象的地址?
  10.                  * 这两个对象应该有两个地址吧?
  11.                  * 这两个对象的内容???
  12.                  */
  13.         }
  14. }
复制代码
有哪位哥能回答一下啊?最好用有代码帮助回答,直观又容易验证

手机发的,格式有不正确的还请哥勿怪……


评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

7 个回复

倒序浏览
是有两个对象,一个是String类型的s2本身,另一个是新new出来的String 对象“abc”
回复 使用道具 举报
同问,求高手解惑...
回复 使用道具 举报
String s1 = "abc";
String s2 = new String("abc");
对于JAVA来讲 . 万事万物都是对象, 都是是封装形式的存在,  对于最基本的数据类型 也不例外 . 当然也包括String .
在JAVA中有一个单独的空间 叫做 常量池 .  常量池中 包含着 所有的 基本数据类型的常量.  
String s1 = "abc";  这句话中 .  只有一个 对象.   这个对象  并不是真的   String s1,  而是 指的 "abc"   
String s1 = "abc"当这句话出现的时候 , JAVA 就会在常量池中寻找 char a  char b  char c   然后 把他们组合起来.  作为一个对象 封装给 s1 .  
就形成了String s1 = "abc" 这句话
String s2 = new String("abc");这句话中的之所有有两个对象.  是因为第一个对象 . 是刚才讲的 "abc"   而第二个对象 就是 new出来的String s2 了.
因为 是new的 而不是 直接赋值.  所有 在内存中 开辟了新的空间 封装了新的对象..  然后 把常量池中 的"abc"这个对象 封装起来 和s2连接上 画了一个等号

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
是有两个对象,第一个是直接赋值的“abc”,第二个是new的abc他们的值虽然相同,但是内存地址不同,如果你要验证的话直接打印出s1 s2,或者用equals方法来验证。

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
首先搞懂三个概念:
常量池:存放基本类型常量和字符串常量。
栈区:只保存基础数据类型的对象和自定义对象的引用(不是对象的);而且每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
堆区:存储的全部是对象(new出来的);
String s1 = "abc"; //  这个abc是在 字符串常量池中
String s2 = new String("abc");  // 通过new了一个新的引用类型,它是放在堆中,同时栈中的引用类型变量(这里的s2)会指向堆中你new出来的东西;【这里一个对象】
                                                第二对象是在常量池中,因为在内存中,是你new一个对象,然后s2指向new出的对象(这个对象给了s2一个地址值),然而里面的“abc“是
                                                在常量池中的,所有会自动有个”abc“的地址值赋给s2 所指向的对象。
类似的贴子,在黑马论坛也很多了,希望能帮到你


   

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
liuzhming 来自手机 中级黑马 2013-7-25 00:04:27
7#
这涉及到缓存池的内容。对于String s1 = "abc";这条语句,将进行如下操作:查找字符串池中是否存在”abc”这个对象,如果不存在,则在字符串池中创建一个”abc”对象,然后将字符串池中的这个对象的地址返回来,赋给引用变量s1,这样s1会指向字符串池中的这个对象。如果存在,则不创建任何对象,直接将字符串池中的这个”abc”对象地址返回来,赋给s1引用。对于String s2 = new String("abc");这条语句,进行如下操作:首先在字符串池中查找有没有”abc”这个字符串对象,如果有,则不在字符串池中再去创建这个对象了,直接在堆中创建一个”abc”字符串对象,然后将堆中的这个”abc”对象的地址返回来,赋给s2引用,导致s2指向了堆中创建的这个字符串对象。如果没有,则首先在字符串池中创建一个”abc”对象,再在堆中创建一个”abc”对象,然后将堆中的这个对象的地址返回来,使得s2指向了堆中所创建的这个”abc”对象。

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
是两个对象,
我们要明白两个概念,引用变量和对象,对象一般通过new在堆中创建,s只是一个引用变量。所有的字符串都是String对象,由于字符串文字的大量使用,java中为了节省时间,在编译阶段,会把字符串文字放在文字池中,文字池的一个好处就是可以把相同的字符串合并,占用一个空间,我们可以用==判断一下两个引用变量是否指向了一个地址即一个对象

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

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