String类

目录

创建String实例的方式:

String 、StringBuilder、StringBuffer对比


创建String实例的方式:

        // 在方法区的常量池生成一个字符串abc,如果
        String str1 = "abc";
        // str2 和str1引用的是同一个字符串,也就是说在常量池中只有一个abc
        String str2 = "abc";
        // 本质上 this.value = new char[0];
        String str3 = new String();
        // 本质上 this.value = original.value;
        String str4 = new String(String original);
        // 本质上 this.value = Arrays.copyOf(value,value.length)
        String str5 = new String(char[] a);
        /
        String str6 = new String(char[] a,int startIndex,int count)

两种创建String对象方法的原理对比: 

例题1:

String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");

System.out.println(str1==str2);  // true
System.out.println(str1==str3);  // false
System.out.println(str1==str4);  // false
System.out.println(str3==str4);  // false

原理如下:

例题2:

class Person{
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Person p1 = new Person("Tom", 12);
Person p2 = new Person("Tom", 13);
// true
System.out.println(p1.name == p2.name);    

原理:

例题3:

class Person{
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

String name1 = new String("Tom");
String name2 = new String("Tom");
        
Person p1 = new Person(name1, 12);
Person p2 = new Person(name2, 13);
// false
System.out.println(p1.name == p2.name);

面试题:

String s = new String("abc")

以上方法在内存中创建了几个对象:

两个;一个是对空间中new结构,另一个是char[ ]对应的常量池中的数据:"abc"。

例题4:

        String s1 = "Hello";
        String s2 = "World";

        String s3 = "HelloWorld";
        String s4 = "Hello" + "World";
        String s5 = s1 + "World";
        String s6 = "Hello" + s2;
        String s7 = s1 + s2;

        System.out.println(s3==s4);  // true
        System.out.println(s3==s5);  // false
        System.out.println(s3==s6);  // false
        System.out.println(s3==s7);  // false
        System.out.println(s5==s6);  // false
        System.out.println(s5==s7);  // false
        System.out.println(s6==s7);  // false

        String s8 = s5.intern();
        System.out.println(s3==s8);  // true

        // s9是常量,常量与常量的运算在常量池中
        final String s9 = "Hello";
        String s10 = s9 + s2;
        System.out.println(s10==s3);  // true

原理:

结论:

  • 常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量
  • 只要其中有一个是变量,结果就在对重
  • 如果拼接的结果调用intern方法,返回值就在常量池中

例题5

public class test03 {
    String str = new String("good");
    char[] ch = {'t', 'e', 's', 't'};

    public void change(String str, char ch[]) {
        str = "test ok";
        ch[0] = 'b';
    }

    public static void main(String[] args) {
        test03 str = new test03();
        str.change(str.str, str.ch);
        System.out.println(str.str);  // good
        System.out.println(str.ch);   // best
    }

}

String 、StringBuilder、StringBuffer对比

1、String :不可变的字符序列,底层使用char[ ]存储

2、StringBuffer:可变的字符序列,线程安全的--效率低;底层使用char[ ]存储

3、StringBuilder:可变的字符序列,jdk5.0新增的,线程不安全的,效率高,底层使用char[ ]存储

源码分析:

String str = new String();  // char[ ] value = new char[0];

String str1 = new String("abc");  // char[ ] value = new char[ ]{'a','b','c'}

 

StringBuffer sb1 = new StringBuffer();  // char[ ] value = new char[16]; 底层创建了一个长度为16的数组

System.out.println(sb1.length());  // 输出结果为0,因为底层返回的是另一个变量count,而不是直接返回数组value的长度

sb1.append('a');  // value[0] = 'a';

sb1.append('b');  // value[1] = 'b'

 

StringBuffer sb2 = new StringBuffer("abc"); char[ ] value = new char["abc".length() + 16]

问题1:扩容问题:如果要添加的数据底层数据盛不下,那就需要扩容底层数组,默认情况下,扩容为原来容量的2倍 + 2,同时将原有数据的元素复制到新的数组中

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值