在Java语言中,所有类似“HelloWorld”的字面值,都是String类的实例;String类位于java.lang包下,是Java语言的核心类,提供了字符串的比较、查找、截取、大小写转换等操作;Java语言为“+”连接符(字符串连接符)以及对象转换为字符串提供了特殊的支持,字符串对象可以使用“+”连接其他对象。字符串的本质是字符数组。
String s1 = "hello"; //静态初始化
String s2 = new String("hello"); //动态初始化
String s3 = new String("hello".getBytes()); //通过字节数组初始化
String s4 = new String("hello".toCharArray()); //通过字符数组初始化
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
System.out.println(s4);
运行结果:
hello
hello
hello
hello
String是引用数据类型,所以String类型的引用都指向堆内存中的一个String类型的对象。
我们把不使用new的方式成为静态初始化,把使用new的方式称为动态初始化。静态初始化的字符串对象是在字符串静态常量池里开辟空间,而动态初始化的字符串对象在堆内存中开辟空间。 有以下代码:
String s1 = "hello";
String s2 = new String("hello");
其内存模型如下图所示:

在我们分析内存模型时,请牢记以下三个口诀: 1)凡是对象一定是在堆内存中开辟空间。 2)凡是new出来的就是对象。 3)凡是new出来的就是不同的对象。
== 用来判断两个引用是否指向同一个对象。 equals用来判断两个引用所指向对象的内容是否相同。
这个道理就好比:妈妈生了一对双胞胎,大林和小林。在外人看来这两个小孩长的一模一样,我们就可以说大林和小林equals为true,但是大林和小林也是两个不同的人,所有他们俩==为false。
结合上面讲的静态初始化和动态初始化,有以下代码:
public static void main(String[] args) {
String s1 = "hello"; //在字符串静态常量池中开辟空间
String s2 = "hello"; //字符串静态常量池中该字面常量如果存在,则无须创建新对象。
String s3 = new String("hello"); //在堆内存中开辟新空间
String s4 = new String("hello".getBytes());//在堆内存中开辟新空间
String s5 = new String("hello");//在堆内存中开辟新空间
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
System.out.println(s1.equals(s3));
System.out.println(s1 == s3);
System.out.println(s3.equals(s4));
System.out.println(s3 == s4);
System.out.println(s3.equals(s5));
System.out.println(s3 == s5);
}
运行结果:
true
true
true
false
true
false
true
false
1)所谓字符串就是把若干个字符串在一起形成字符序列,字符串的本质是字符数组。
2)字符串常见的构造方式有: String s = "xxx"; String s = new String("xxxx"); String s = new String(byte[] arr); String s = new String(char[] arr);
3)字符串分为静态初始化和动态初始化,静态初始化的字符串对象是在字符串静态常量池里开辟空间,而动态初始化的字符串对象在堆内存中开辟空间。
4)== 用来判断两个引用是否指向同一个对象。equals用来判断两个引用所指向对象的内容是否相同。