黑马程序员技术交流社区

标题: 帮忙分析一下这个程序 [打印本页]

作者: 杨文宇    时间: 2012-7-26 21:05
标题: 帮忙分析一下这个程序
本帖最后由 杨文宇 于 2012-7-26 22:23 编辑

public class Demo1 {
        public static void main(String[] args) {
                String s = new String("abc");
                String s1 = "abc";
                String s2 = new String("abc");
                String s3 = new String(new String("abc"));
                              //都搞不懂,麻烦详细说说
                System.out.println( s == s1.intern() );
                System.out.println( s == s2.intern() );
                System.out.println( s1 == s2.intern() );
                System.out.println( s1 == s3.intern() );
                System.out.println( s.intern() == s3.intern() );


        }
}

作者: 朱烈葵    时间: 2012-7-26 21:26
我也是第一次见这么写的,我也想了解下
作者: 罗宵    时间: 2012-7-26 21:26
API中:当String调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。 调用之后就返回一个String类型,然后去常量池中寻找,如果有就直接返回池中的字符串。
String s = new String("abc");
String s1 = "abc";
String s2 = new String("abc");
String s3 = new String(new String("abc"));
虽然上面四个的地址值都不同,而且s1中的"abc"就在常量池。
  System.out.println( s == s1.intern() );s1.intern() 就是常量池的"abc",而s是在堆内存中new的一个对象,所以为false;
System.out.println( s == s2.intern() );和上面一样s2.intern()之后也是量池的"abc",所以false;
System.out.println( s1 == s2.intern() );s2.intern()之后也是量池的"abc",s1中的"abc"就在常量池,所以都是同一个,所以true;
System.out.println( s1 == s3.intern() );同上,
System.out.println( s.intern() == s3.intern() );同上,

作者: 贾成龙    时间: 2012-7-26 21:35
class Demo1
{
        public static void main(String[] args)
        {
                String s = new String("abc");
                String s1 = "abc";
        String s2 = new String("abc");
        String s3 = new String(new String("abc"));
        System.out.println( s == s1.intern() );//false
        System.out.println( s == s2.intern() );//false
        System.out.println( s1 == s2.intern() );//true
        System.out.println( s1 == s3.intern() );//true
        System.out.println( s.intern() == s3.intern() );//true
      /*
             "=="判断两个字符串的地址是否相同
                 equals判断两个字符串的内容是否相同
                 而intern是将字符串转化成标准的字符串写法,intern遵循的规则是:它遵循以下规则:
                 对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
          */
    }
}
作者: 黄珊珊    时间: 2012-7-26 21:38
本帖最后由 黄珊珊 于 2012-7-26 23:04 编辑


String s = new String("abc");
这句不用判断String池中是否存在字符串"abc",首先在堆中新建一个String对象"abc",然后将其赋给s。
该代码可以分为以下四步来看:
1)在栈中开辟一块空间存放引用s;
2) 在堆中开辟一块空间存放一个新建的String对象"abc";
3) 引用s指向堆中的新建的String对象"abc";
4) s所指代的对象地址为堆中地址,而常量"abc"地址在池中,输出为false;

String s1 = "abc";
首先查看String池中是否存在字符串"abc",假如存在则直接将"abc"赋给s1,假如不存在则先在字符串池中新建一个字符串"abc",然后再将其赋给s1。




作者: 杨文宇    时间: 2012-7-26 21:56
感谢楼上,感觉String白学了。再回去重看一下
作者: 杨文宇    时间: 2012-7-26 22:20
黄珊珊 发表于 2012-7-26 21:38
我详细的说下分析的步骤吧。
String s = new String("abc");
这句代码可以分为四步来看:

String s2=String( "Hello ");
我查了下资料。
jvm首先在String池内里面看找不找到字符串 "Hello ",找到,不做任何事情,否则,创建新的string对象,放到string池里面。由于遇到了new,还会在内存上(不是string池里面)创建string对象存储 "Hello ",并将内存上的(不是string池内的)string对象返回给s2。
作者: 黄珊珊    时间: 2012-7-26 23:21
杨文宇 发表于 2012-7-26 22:20
String s2=String( "Hello ");
我查了下资料。
jvm首先在String池内里面看找不找到字符串 "Hello ",找到, ...

String s2=String( "Hello ");
这句代码的过程正如你所说。
但与String s = new String("abc");这句代码不同,它有一个new,不论其在String池中是否有字符串,都先在堆中新建一个String对象"abc",然后再将其赋给s。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2