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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李力 中级黑马   /  2013-4-7 18:40  /  1908 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

String s1 = "Hello Word";
String s3 ="Hello Word";
String s2=new String("Hello Word");
String s4=new String("Hello Word");
这四条语句有什么不同吗?
最后s1,s2,s3,s4的内容都是"Hello World";
那么它们又有什么是不同的呢?

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

9 个回复

倒序浏览
    网上搜索一下,很容易找到答案的。如下:
     java虚拟机里有一个区域叫方法区,方法区里有一个常量区,如果你是String s1= "Hello Word",虚拟机认为"Hello Word"是常量,放在常量区。下次你再定义String s3 = "Hello Word", 虚拟机并不新创建任何东西,而是连到刚才常量区里的"Hello Word",所以不管是equal还是==,都相等,因为值和地址都相等。
另外还有一个区域叫堆,如果String s2= new String("Hello Word"), 虚拟机会创建对象放到堆里,再String s4 = new String("Hello Word"),会在堆里放两个对象。所以==就是false,因为两个对象地址不同。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
String s1 = "Hello Word";
String s3 ="Hello Word";

String s2=new String("Hello Word");
String s4=new String("Hello Word");
可能你还没有看后面的关于String的视频,先给你大概说下
String类型的变量不是基本类型的变量,是引用类型的变量。
s1和s3是两个String类型的引用,指向栈内存中的同一个变量“Hello Word”,如果此时用.equals()方法进行对比,结果是true,说明是指向同一块内存
s2与s4则不同,new关键字的作用是在堆内存中开辟一块新的内存空间来存放内容,无论这个内容是否存在,如果此时用.equals()方法进行对比,结果是false,说明是指向不同的内存
要彻底弄清这个问题,需要知道堆栈内存的适用性和基本数据类型与引用数据类型的区别

希望能给你个思路~~

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
String类的本质是字符数组char[],其次String类是final的,是不可被继承的,再次String是特殊的封装类型,使用String时可以直接赋值,也可以用new来创建对象,但是这二者的实现机制是不同的。
第一句的真正含义是在String池中创建一个对象”Hello World”
第三句实际上是创建了两个实体 自身一个 new出来一个

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
s1 和 s3 的区别:   对象变量名不同。
s1,s3 和 s2,s4 的区别: s1,s3是一个对象,而s2,s4有2个对象。
s2 和 s4 的区别:new 之后,在堆内存地址不同。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
s1和s3的内容是存储在字符串池中,指向的是同一个地址.s2和s4是在内存中分别开辟了新的空间,把内容放进去,不是访问字符串池,地址不一样

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
s1和s3是存在方法区中的,s1创建"Hello Word"后虚拟机将地址赋给了s3.
s2和s4是分别在堆内存中创建了两个对象(new了一个和"Hello Word"),并没有操作方法区

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
      简单的来说,s1和s3这个只是建立了一个对象,s2和s4是建立了两个对象,
          String s2=new String("Hello Word");
          第一部分:这个先是运行"Hello Word",在string池中生成一个对象(如果该池中没有存在和该对象内容相同的对象,就重新生成,否则就直接用该对象)
      第二部分:执行new,就会执行string的构造函数,建立对象,这个对象是放在堆内存中的,s2变量保存的是该对象的地址值,也就是引用
          String s1 = "Hello Word";也就是只做上面所介绍的第一部分
  
      用==来对字符串来比较的话,判断是依据是对象的地址值是否一致
      用String类的equals方法去比较字符串的话,判断的依据是对象的字符串值是否一致

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
String s1 = "Hello Word";
String s3 ="Hello Word";
String s2=new String("Hello Word");
String s4=new String("Hello Word");
首先:s1和s3就创建了一个对象,而s2和s4有两个对象,一个是new String("Hello Word")创建的,另外一个是Hello World,然而对象指向的是 new String("Hello Word")创建的,另外一个等待被回收。
其次:s1创建过后,如果再创建s3的话,那么内存就不会再开辟新的内存空间了。因为s1和s3创建的字符串是一样的,s3要是使用的话,直接从字符串池中取出就可以使用。这样就节省了内存空间。
最后:s2和s4是两个不同的对象,他们所指向的地址也是不一样的。是两个不同的空间。

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
关于String类的说明
1.String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能
再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的(immutable).

2.String类有一个特殊的创建方法,就是使用""双引号来创建.例如new String("i am")实际创建了2个
String对象,一个是"i am"通过""双引号创建的,另一个是通过new创建的.只不过他们创建的时期不同,
一个是编译期,一个是运行期!

3.java对String类型重载了+操作符,可以直接使用+对两个字符串进行连接.

4.运行期调用String类的intern()方法可以向String Pool中动态添加对象.



单独使用""引号创建的字符串都是常量,编译期就已经确定存储到String Pool中.使用new String("")创建的对象会存储到heap中,是运行期新创建的.变量s2,s4中存储的内容是JVM在堆中开辟的两个String对象的内存地址
.

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

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