1. String 类

1.1 创建方式

  • 1.1.1 直接赋值String s = "宇川";,字符串存储在字符串常量池中,相同内容只存一份
  • 1.1.2 new 创建String str = new String("李四");,在堆内存中创建新对象,每次 new 都是独立地址

1.2 == 与 equals 的区别

  • 1.2.1 == 比较地址值:判断两个变量是否指向同一块内存
  String s = "宇川";
  String s2 = "宇川";
  System.out.println(s == s2);   // true,常量池中同一地址
 
  String s3 = new String("李四");
  String s4 = new String("李四");
  System.out.println(s3 == s4);  // false,堆中两个独立地址
  • 1.2.2 equals() 比较内容:判断两个字符串的内容是否相同,与地址无关
  System.out.println(s2.equals(s3)); // true,内容相同
  System.out.println(s3.equals(s4)); // true,内容相同

1.3 null 的注意事项

  • 1.3.1 null 不能调用方法null 调用任何方法都会抛出 NullPointerException
  • 1.3.2 安全写法:将非 null 的字符串放在 equals() 的调用方,把可能为 null 的变量作为参数传入
  String str = null;
  // str.equals(s3);   // 报错:NullPointerException
  s3.equals(str);      // 安全:返回 false

1.4 字符串的不可变性

  • 1.4.1 String 是不可变对象:字符串内容一旦创建不可修改,对字符串变量重新赋值本质是指向了新的地址,原内容不变
  • 1.4.2 示例
  String s1 = "hello";
  System.out.println(Integer.toHexString(s1.hashCode())); // 某个哈希值
 
  s1 = "hello" + "world"; // s1 指向新地址,原 "hello" 不变
  System.out.println(Integer.toHexString(s1.hashCode())); // 不同的哈希值
  • 1.4.3 对象地址不变:与 String 不同,普通对象修改属性后地址值不变
  Student student = new Student(20, "炫光", "男");
  System.out.println("student = " + student); // 地址:2f4d3709
  student.setAge(23);
  System.out.println("student = " + student); // 地址:2f4d3709(不变)

2. 示例代码

package com.itszt.day04;
 
public class Demo05 {
    public static void main(String[] args) {
        // 直接赋值:常量池,相同内容同一地址
        String s = "宇川";
        String s2 = "宇川";
        System.out.println(s == s2);   // true
 
        // new 创建:堆内存,每次独立地址
        String s3 = new String("李四");
        String s4 = new String("李四");
        System.out.println(s2 == s3);  // false
        System.out.println(s3 == s4);  // false
 
        // equals 比较内容
        System.out.println(s2.equals(s3)); // true
        System.out.println(s3.equals(s4)); // true
 
        // null 安全写法
        String str = null;
        System.out.println(s3.equals(str)); // false(安全)
 
        // 字符串不可变性:重新赋值指向新地址
        String s1 = "hello";
        System.out.println(Integer.toHexString(s1.hashCode()));
        s1 = "hello" + "world";
        System.out.println(Integer.toHexString(s1.hashCode())); // 哈希值不同
 
        // 普通对象修改属性,地址不变
        Student student = new Student(20, "炫光", "男");
        System.out.println("student = " + student);
        student.setAge(23);
        System.out.println("student = " + student); // 地址相同
    }
}

3. 总结

知识点核心要点
直接赋值存入常量池,相同内容共享同一地址
new 创建存入堆内存,每次创建独立地址
==比较地址值
equals()比较字符串内容
null 安全写法非 null 字符串调用 equals(),null 作参数
字符串不可变重新赋值是指向新地址,原内容不变
对象地址不变修改属性不改变对象地址