Java之String关键字解析
Java之String关键字解析
1. String类
- String类是final类,即String类不能被继承,并且它的成员方法都默认为final方法。
Java中被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。
- String类底层是char数组来保存字符串的,对String对象的任何改变都不会影响到原对象,相关的任何change操作都会生成新的对象。
2. 字符串常量池
在class文件中有一部分用来存储编译期间生成的字面常量以及符号引用,这部分就叫做class文件常量池,在运行期对应着方法区的运行时常量池。
JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存就被称为字符产常量池或字符串字面量池。
2.1 工作原理
当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。
2.2 实现前提
字符串常量池实现的前提条件:
- Java中String对象不可变,可以安全保证多个变量共享同一个对象。
若String对象可变,则一个引用操作改变了对象的值,那其它的变量也会被影响,导致不一致性
3. 实例
String str1 = "hello"; // str1指的是方法区中的字符串常量池中的"hello",编译时期就知道
String str2 = "he" + new String("llo"); // str2必须在运行时才知道str2是什么,所以其指向的是堆里定义的字符串"hello",这两引用不同。
str1.equals(str2); // 返回true,因为String类重写了equals方法
//编译器编译期不知道"he" + new String("llo")的内容是什么,所以不敢贸然把"hello"对象的引用赋给str2
String str3 = "he" + "llo";
str1.equals(str3); // 返回true
new String("xy") // 实际上创建了2个String对象,一个使用"xy"通过双引号创建的(在字符串常量池,编译期),另一个通过new创建的(在堆里,运行时),创建时期不同。
String s = "a" + "b" + "c"; // "a","b","c" 都是常量,编译时就直接存储他们的字面值,而不是他们的引用,所以编译期就直接将他们连接的结果提取出来变成"abc"了。
package io.itracybryant.fd;
public class StringInEqual {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
String d = "ab" + "c";
String d1 = "ab";
String d2 = "c";
String e = d1 + d2;
String f = "ab" + new String("c");
System.out.println(a == b);
System.out.println(a == c);
System.out.println(a == d);
System.out.println(a == e);
System.out.println(a == f);
System.out.println("---------------------------");
System.out.println(a.equals(b));
System.out.println(a.equals(c));
System.out.println(a.equals(d));
System.out.println(a.equals(e));
System.out.println(a.equals(f));
System.out.println("---------------------------");
System.out.println(a.hashCode() == b.hashCode());
System.out.println(a.hashCode() == c.hashCode());
System.out.println(a.hashCode() == d.hashCode());
System.out.println(a.hashCode() == e.hashCode());
System.out.println(a.hashCode() == f.hashCode());
}
}