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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© toShareBeauty 高级黑马   /  2013-7-9 11:49  /  889 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨兴庭 于 2013-7-10 22:30 编辑

下面这个代码片段产生了几个对象:
  1. Object s1 = new String("Hello");
  2. Object s2 = new String("Hello");

  3. if(s1 == s2) {
  4.   System.out.println("s1 and s2 are ==");
  5. }else if (s1.equals(s2)) {
  6.   System.out.println("s1 and s2 are equals()");
  7. }
复制代码

评分

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

查看全部评分

9 个回复

倒序浏览
3个String对象;第一次new会在堆里创建一个和在字符串池里创建一个,第二次因为字符串池里已经有一样的了就不用在里面创建,只用在堆里创建一个就行,像创建普通对象一样

评分

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

查看全部评分

回复 使用道具 举报 1 0
一共3个对象,两个new出来的,还有“abc”也是一个对象

评分

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

查看全部评分

回复 使用道具 举报
运行结果是什么
回复 使用道具 举报
本帖最后由 toShareBeauty 于 2013-7-9 14:53 编辑
草貌路飞 发表于 2013-7-9 11:55
3个String对象;第一次new会在堆里创建一个和在字符串池里创建一个,第二次因为字符串池里已经有一样的了就 ...

{:soso_e179:}高手!能不能更加详细的说一下,字符串池相关的内容,字符串池在那个堆还是栈中,完整的代码是下面的样子:
  1. class StringDemo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Object s1 = new String("Hello");
  6.                 Object s2 = new String("Hello");
  7.                  
  8.                 if(s1 == s2) {
  9.                         System.out.println("s1 and s2 are ==");
  10.                 }else if (s1.equals(s2)) {
  11.                         System.out.println("s1 and s2 are equals()");
  12.                 }
  13.         }
  14. }
复制代码
这是我模拟 jvm 跑了一下这个程序,有些地方也不太清楚:

当加载 StringDemo 类的时候,"Hello" 是局部变量的常量,它会放在 JVM 的运行时数据区——>方法区——>appClassLoader域——>StringDemo类字节码信息——>常量池 里面么(1.在这个常量池里面,"Hello" 还是以字符串对象的形式存在么,还是引用形式,因为 String 不是 jvm 支持的8种基本数据类型,这个地方 String 是不是还要转为字符,并以字符数组的形式存在于堆内存,让后再用 字符数组 封装成 String 对象, 保存在堆内存中,常量池中保存的只是对个对象的引用)? 当 JVM 执行 StringDemo.main  函数的时候,在 Java 栈 压入 main 函数栈帧,在栈帧——>局部变量区 分配 s1 s2 两个局部变量的空间,并在栈帧的操作栈分配一个引用型存储单元,保存 "Hello" 对象的引用(2.这个引用是执行堆的对象还是只想常量池?),然后让 BootStrap Class Loader 加载 String 类,并动态修改 StringDemo 类在方法区中的常量池里面关于 String 类的符号引用为直接引用(3.这个地方是不是应该在常量池使用 String 对象的时候就做了?),之后调用 String 的构造方法,在 Java 栈 中压入 String 对应的构造函数栈帧,前面指向 "Hello" 的操作栈变量空间,暂时和 String 构造函数栈帧的局部变量共享同一份空间,此时在堆内存中给 String 类分配一个对象,jvm 执行 String 构造函数,完成后返回一个 String 对象的引用(4.这个String 对象的引用保存在哪里是 String 构造函数栈帧的局部变量区还是操作数栈),Java 栈弹出 String 构造函数 栈帧,s1 对应的栈帧的局部变量域中的内存单元指向这个 String 对象。

从这个分析来看有4个对象,一个 char[] ,3 个 String


回复 使用道具 举报
本帖最后由 toShareBeauty 于 2013-7-9 14:54 编辑

运行结果是:s1 and s2 are equals()
因为 s1 s2 不是指向同一个对象,String 类重写了 Ojbect 的 equals 和 hashcode 方法, == 和 equals 就不同了。
回复 使用道具 举报
应该是1个对象,
System.out.println( s1.hashCode());//  返回 的哈希码值是69609650
  System.out.println(s2.hashCode());// 返回 的哈希码值也是69609650
  System.out.println(s1.equals(s2));///返回的是ture
所以s1和s2指向的都是同一个对象。那就是Hello。
回复 使用道具 举报
本帖最后由 toShareBeauty 于 2013-7-9 14:50 编辑
左手神刀 发表于 2013-7-9 14:06
应该是1个对象,
System.out.println( s1.hashCode());//  返回 的哈希码值是69609650
  System.out.print ...

String 类型的 hashcode 已重写,返回的是 String 类中的 char[] 类型成员的 hashcode ,这两个 hashcode 一致说明他们对应的 char[] 对象是同一个。
回复 使用道具 举报
于丹 初级黑马 2013-7-10 10:26:52
9#
产生1个对象
回复 使用道具 举报
hx32 高级黑马 2013-7-10 10:31:56
10#
三个,s1和s2和“Hello”
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马