天天看点

Java中String对象不可变及字符串常量池

字符串定义:一个字符串是由多个字符组成的一串数据(字符序列,字符数组)

构造方法:

  • 空字符串
  • byte[] -----> String
  • char[] -----> String
public class Summarize {
    public static void main(String[] args) {
        //空字符串
        String s = new String();
        
        //利用字节数组创建字节数组所表示的字符串
        byte[] bytes = {97, 98, 99, 100};
        String s1 = new String(bytes);
        System.out.println(s1);

        //利用字节数数组的一部分,从byte数组的offset开始的length个字节值
        String s2 = new String(bytes, 1, 3);
        System.out.println(s2);

        //利用字符数组创建字符数组代表的字符序列
        char[] chars = {'A', 'B', 'C', 'D'};
        String s3 = new String(chars);
        System.out.println(s3);

        //public String(String original)
        String s4 = new String("abcdef");
        System.out.println(s4);
    }
}
           

String对象不可变

String对象一旦被创建后,对象所有的状态及属性在其生命周期内不会发生任何变化。

思考:

键盘录入一个任意字符串s,并用一个temp字符串引用也指向它。这个时候修改s字符串的内容,请问temp字符串的内容会随之改变吗?

public class Demo {
    public static void main(String[] args) {
        // 创建Scanner对象
        Scanner scanner = new Scanner(System.in);
        // 键盘接收nextLine -- > s
        String s = scanner.nextLine();
        // temp 指向
        String temp = s;
        // 更改s内容
        s = "aaa";
        // 打印
        System.out.println("temp = " + temp);
        System.out.println("s = " + s);
    }
}
           

答案:不会

原因与本质

  • String是一个final类,代表不可变的字符序列
  • 字符串是常量,用双引号引起来,他们的值在创建之后不可更改
  • String对象的内容是存储在字符数组value[ ]中的
Java中String对象不可变及字符串常量池

字符串常量池

字符串的分配和其他对象分配一样,是需要消耗高昂的时间和空间的,而且字符串使用的非常多,

JVM为了提高性能和减少内存的开销,在实例化字符串对象的时候进行了一些优化:

使用字符串常量池

首先要明确,Java的双引号引起来的字面值常量字符串,它们都是对象。

这些对象比较特殊,程序在编译时期就能确定它们的值

每当创建字符串常量对象时,JVM会首先检查字符串常量池,如果该字符串对象引用已经存在常量池中,那么就直接返回常量池中的实例引用。如果字符串对象引用不存在于常量池中,就会实例化该字符串并且将其引用放到常量池中。

//练习
class Demo1{
    public static void main(String[] args) {
        String s1 = new String("hello");
        String s2 = new String("hello");
        //String.equals默认重写了Object.equals方法,比较的是字符串的值
        System.out.println(s1 == s2);  //false
        System.out.println(s1.equals(s2));  //true

        String s3 = new String("world");
        String s4 = "world";
        System.out.println(s3 == s4);  //false
        System.out.println(s3.equals(s4));  //true
    }
}
           

字符串常见问题与练习

class Demo2{
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hel" + "lo";
        String s3 = "Hel" + new String("lo");
        String s4 = new String("Hello");
        String s5 = "H"; String s6 = "ello";
        String s7 = s5 + s6;

        System.out.println(s1 == s2);  //true
        System.out.println(s1 == s3);  //false
        System.out.println(s3 == s4);  //false
        System.out.println(s1 == s7);  //false
    }
}