一、空字符串 ""
类型:"" 是一个空字符串(String),长度为0,占内存,在内存中分配一个空间,可以使用 Object 对象中的方法。(例如:"".toString() 等)
内存分配:使用双引号直接创建的字符串,称为字符常量。字符常量放在内存中的常量池。表示声明一个字符串类型的引用,其值为 "" 空字符串,这个引用指向 a 的内存空间、
//不变性
String a = "tom"; //字符常量,放在常量池
a = "jack"; //常量池中有两个String对象
String b = "tom"; //创建流程:先判断常量池是否存在tom,如果有,就直接指向
System.out.println(a); //jack 当重新赋值,会在内存中再次分配一块新的空间
二、null
类型:null 是空引用,表示一个对象的值,没有分配内存,调用 null 的字符串的方法会抛出空指针异常。
@Test
public void a52() {
String a = null;
System.out.println(a.length()); // java.lang.NullPointerException
}
内存分配:表示声明一个字符串对象的引用,但指向 null,也就是说没有指向任何内存空间。
new String() 创建一个字符串对象的默认值为 "" 空字符串
@Test
public void a52() {
String str1 = ""; // str1 对应一个空串,声明对象的引用
String str2 = null; // str2 引用为空
//构造方法创建 ---new
String s1 = new String("aaa");//这里把"aaa"代表的对象的引用存到了s1中
s1= new String("bbb");//这里又把另一个对象"bbb"存到了s1中,所以s1就不是指向原来的"aaa"了,而是指向"bbb"了,新的空间, aaa等着回收
}
注意:str1 和 s1 被实例化,而str2没有实例化,但 str1 和 s1 所指的地址不同,但值一样,都为空。
有时要检查一个字符串不是 null 也不为空字符串,这种情况下就需要使用以下条件:
if (str != null && str.length() != 0)
注意:首先要检查 str 不为 null。如果在一个 null 值上调用方法,会出现空指针异常错误。
@Test
public void a52() {
String str1 = new String();
String str2 = null;
String str3 = "";
System.out.println(str3.length()); // 空字符串""的长度为0
System.out.println(str2.length()); // 抛出空指针异常
System.out.println(str1); // 输出""
System.out.println(str1 == str2); // 内存地址的比较,返回false
System.out.println(str1.equals(str2)); // 值的比较,返回false
System.out.println(str2 == str3); // 内存地址的比较,返回false
System.out.println(str3.equals(str2)); // 值的比较,返回false
System.out.println(str1 == str3); // 内存地址的比较,返回false
System.out.println(str1.equals(str3)); // 值的比较,返回true
}
三、总结
null 对象是一个特殊的对象,它可以是任何类型。它只是作为一个标记而已,只是为了标记不存在而存在的。也没必要去追究它在内存是什么样。null 就是一个标记而已。容器可以接受一个空对象,但是一个空引用则是不接受的。
四、equals 为什么要把常量放在前面
str.equals("abc");
如果 str 是 null,空对象是没有 equals 方法的,会抛出空指针异常
"abc".equals(str);
如果 str 是null,最终始终返回的都是 false。也就是说 null 在前会报空指针,null 在后就不会报,会返回 false
总结
- 空指针就是空引用,Java 空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常。可以理解,成员变量和方法是属于对象的(除去静态),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和方法,这个时候用它去调用某些属性和方法,当然会出现空指针异常。
- null 是所有引用类型的默认值(包装类),如果没有让一个引用指向一个实际存在的对象,它的默认值就是 null ,null 调用任何方法都会报空指针,空字符串则不会,因为已经分配了内存地址。