zoukankan      html  css  js  c++  java
  • jdk分析之String

     
    public class StringDemo01 {
        public static void main(String[] args) {
            String s1 = new String("abc"); // a 
            String s2 = "abc"; // b 
            String s3 = new String("abc"); // c
    
            System.out.println(s1 == s2); //false
            System.out.println(s1 == s3); //false
            System.out.println(s2 == s3); //false
    
            System.out.println(s1 == s1.intern()); //false
            System.out.println(s2 == s2.intern()); //true 
            System.out.println(s1.intern() == s2.intern()); //true
    
            String lo = "lo";
            String hel = "hel";
            System.out.println("hello" == "hel" + "lo"); // d //true
            System.out.println("hello" == "hel" + lo); // e //false
            System.out.println("hello" == hel + "lo"); // f //false
        }
    }

    1、生成几个对象

    问题:当执行完程序的第a、b、c行之后分别生成几个对象,分别是什么?原因?

    1)执行完a后,生成2个对象:

    首先先到String Pool中寻找是否有名称为"abc"的字符串,没有的话在String Pool中新生成一个"abc"对象1,而new String("abc")操作又会在Java内存的堆中生成一个"abc"String类对象2,

    变量s1是一个引用,存放在栈中并指向堆中的"abc"String对象;

    2) 执行完b后,生成0个对象:

    String s2= "abc"; 此句程序在执行过程中也会先到String Pool中寻找名称为"abc"的字符串对象,因为在String s1 = new String("abc");时已经在String Pool中生成了"abc"对象,故执行完

    这句之后同样存在于栈的s2对象指向String Pool中的"abc"String对象,即s2中存放"abc"String对象在String Pool中的地址;

    3) 执行完c后,生成1个对象:

    同样的道理,首先会到String Pool中查找是否有"abc"String对象,发现已经存在,然后又通过new的方式在中生成一个新的"abc"String对象,并将其地址赋给引用变量s3;

    在此示例中三个引用变量s1、s2、s3分别指向三个不同的对象,存放着三个不同的内存地址,故三者当中任意者用"=="来比较都是false。

    s1--------堆中的一个对象,此对象是String Pool中对象的一个拷贝;

    s2--------String Pool常量池中的"abc"String对象;

    s3--------堆中的一个对象,此对象也是String Pool中对象的一个拷贝;

    ==判断小结

    1)对于原生数据类型来说"=="比较的是数据的数值
    2)对于引用数据类型来说"=="比较的永远是对象的内存地址

    2、intern

    查看JDK文档可知如果有两个String类型s和t,当且仅当s.equals(t)时,s.intern()==t.intern(),即如果s和t的内容相等时s.intern()和t.intern()都是返回String Pool中同一个对象的引用,

    既然是同一个对象的引用地址肯定一样。 分析s.intern()可知,首先到String Pool常量池中查找是否有"abc"字符串,如果有那么s.intern()的返回值就是常量池中"abc"的地址,如果没有,那么会先添加到string pool中去,然后将地址返回

    所以可以得到如下关系:s.intern()=s1.intern()=s2.intern()=s1

    s1指向的是堆,而s1.intern()指向的是常量池中;

    s2指向的是常量池,s2.intern()指向的也是常量池;

    s1. intern()指向的是常量池,s2.intern()指向的也是常量池;

    3、字符串拼接

    对于第d行"+"两端是两个字面值即常量,故会拼接成一个"hello",然后在String Pool常量池中可以找到,不生成新的对象,等号两端的地址都是String Pool中" hello"的地址,所以相等,返回true。

    对于第e,f行"+"两端其中一个是字面值即常量而另一个则是变量,无法进行拼接,故会在堆中生成一个"abc"的对象,堆中一个对象和String Pool常量池中一个对象当然是两个对象,地址值肯定不相

    等,所以返回false。

    常量池:JVM中一块独立的区域存放字符串常量和基本类型常量(public static final)

    4、在Java中一个字符串能否表示一个汉字?

    在Java中一个字符表示16位,相当于两个字节(1 byte = 8 bit),而一个汉字占用两个字节。

    5、String s = "Hello"; s = s + " world!";这两行代码执行后,原始的String对象中的内容到底变了没有?

    String对象的内容是不能改变的,最后虽然指向了helloworld,但是原始的String对象的内容还是hello并没有改变,只是现在不指向它罢了。

    6、String s = new String("xyz");创建了几个String Object? 二者之间有什么区别?

    创建了2个对象,一个在string pool中一个在堆中

    7、String 和StringBuffer的区别

    String是final类型,内容不可改变的,StringBuffer的内容是可以改变的;

    String重写了equals和hashCode方法,而StringBuffer则没有。

    8、StringBuffer和StringBuilder的区别

    StringBuffer是线程安全的;

    StringBuilder是非线程安全的性能高点,推荐使StringBuilder,JDK5以后出现。

    9、下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d"

    一个。JVM在编译时会优化,相当于直接定义了一个”abcd”的字符串;

    String s = "a"+"b"+"c";会生成几个对象?

    只会生成一个对象,编译期就能确定存储到常量池中。

    使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在中;

    10、String练习

    String str1 = "a";
    String str2 = "b";
    String str3 = "ab";
    String str4 = str1 + str2;
    String str5 = new String("ab");
    
    System.out.println(str5.equals(str3));  //true
    System.out.println(str5 == str3); //false
    System.out.println(str5.intern() == str3); //true
    System.out.println(str5.intern() == str4); //false
    
    
    String a = new String("ab");
    String b = new String("ab");
    String c = "ab";
    String d = "a" + "b";
    String e = "b";
    String f = "a" + e;
    
    System.out.println(b.intern() == a); //false
    System.out.println(b.intern() == c); //true
    System.out.println(b.intern() == d); //true
    System.out.println(b.intern() == f); //false
    System.out.println(b.intern() == a.intern()); //true
    
    
    String a = "abc";
    String b = "abc";
    String c = "a" + "b" + "c";
    String d = "a" + "bc";
    String e = "ab" + "c";
    
    System.out.println(a == b); //true
    System.out.println(a == c); //true
    System.out.println(a == d); //true
    System.out.println(a == e); //true
    System.out.println(c == d); //true
    System.out.println(c == e); //true
  • 相关阅读:
    javascript关于继承
    javascript组合继承
    javascript创建对象的几种模式
    Angularjs学习笔记6_table1
    Angularjs学习笔记5_form1
    Angularjs学习笔记3_datepicker
    Angularjs学习笔记2_添加删除DOM元素
    Angularjs学习笔记5_scope和$rootScope
    Angularjs学习笔记1_基本技巧
    RabbitMQ基础概念
  • 原文地址:https://www.cnblogs.com/luogankun/p/3966131.html
Copyright © 2011-2022 走看看