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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 廖智 中级黑马   /  2012-10-6 22:34  /  2144 人查看  /  5 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 廖智 于 2012-10-6 22:43 编辑

创建字符串对象有两种方式
方式一:String s = new String("abc");
方式二:String s = "abc";
第一种字符串对象创建方式会在堆内存中创建一个对象,如果常量池中没有这个对象,还会在常量池中创建一份。
在内存中引用变量s 指向的是堆内存中的对象。
想问下常量池中的那个对象是怎么指向的?也是s指向吗?
求帮忙分析下内存情况!

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
你这么单独看是看不出区别来的
  1. public class MyTest {
  2.         public static void main(String[] args) {
  3.                 String s1=new String("abc");
  4.                 String s2="abc";
  5.                 String s3="abc";
  6.                
  7.                 String s4=new String("abc");
  8.                
  9.                 System.out.println(s1==s2);//false
  10.                 System.out.println(s2==s3);//true
  11.                 System.out.println(s1==s4);//false
  12.         }
  13. }
复制代码
可以看出s1和s2指向的不是同一个对象,而是分别在内存中创建了对象;
而s3则和s2指向的是同一对象;
又可以看出s1、s4指向不是同一对象。
由此可以看出,使用new来新建一个字符串时,是无视内存中的字符串对象,直接新建立对象;
而使用 String s="string" 方式时,会直接引用内存中已有的字符串对象。

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
画个内存图来回复你
   你自习看看这个内存图应该就能明白了。
回复 使用道具 举报
本帖最后由 廖智 于 2012-10-6 22:58 编辑
陈冲 发表于 2012-10-6 22:44
你这么单独看是看不出区别来的可以看出s1和s2指向的不是同一个对象,而是分别在内存中创建了对象;
而s3则 ...
谢谢!
我也分析了下!
使用new来创建对象时,比较的应该是堆内存中的对象,不使用new来创建对象,比较的应该是常量池中的对象。
由你的比较来分析,指向堆内存和常量池的引用明显不是同一个。那常量池的那个对象是怎么指向的呢?
现在就是搞不懂常量池中对象的引用指向!
回复 使用道具 举报
本帖最后由 孙含庆 于 2012-10-6 23:42 编辑


class  StringDemo
{
        public static void main(String[] args)
        {
                String java1 = "java";

                String java2 = "java"; //用双引号创建

                String java3 = new String("java"); //用String类的构造方法创建

                String java4 = new String("java");
                                                
                                //用双引号创建对象的话,JVM会先去字符串缓冲池找相同内容的字符串,找不到,就在池子里放一个新的。

                                //现在内存中有三个对象 java1 和 java2 使用的是缓冲区中的同一个存储对象。

                                //用构造方法创建对象时,JVM 会和创建其他类型对象一样,一调用,就在堆内存创建一个新的。

                                //java3 和 java4 是不同的存储对象,只是对象中的内容相同

                                //两种创建方法有区别,一般,建议使用双引号的方式创建,该方式用缓冲池机制,效率高。
        }
}

java 虚拟机内部就是根据你创建对象的方式来区分对象放在哪里的,你要是问 JVM 底层内部是怎么做这个动作,

那么建议初期学习阶段不要去这么钻牛角尖,会影响学习心情的,先按规则来学,等都学会了,会用了,就慢慢都懂了。
回复 使用道具 举报
so easy:
方式一的s指向的是堆内存的一个对象,该对象有个引用(就是一个String型的成员属性)指向了字符串池中的"abc"对象.
方式二的s直接指向常量池中的"abc"对象.
所以方式一和方式二的s指向的不是同一个对象.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马