Talk is cheap
先放个程序:
public class Ha {
public static void main(String[] args) {
//String作为基本类型来使用
String a="hello";
String b="hello";
System.out.println(a==b);
System.out.println(a.equals(b));
//String作为对象来使用
String c = new String("hello");
String d = new String("hello");
System.out.println(c==d);
System.out.println(c.equals(d));
String e = new String("hello");
String f = "hello";
System.out.println(e==f);
System.out.println(e.equals(f));
}
}
程序输出:
true
true
false
true
false
true
首先, 在创建String时有两种方法,一种是作为对象来创建,保存在堆区
中;另一种是作为基本类型来创建,保存在常量池
中。
其次,==比较的是对象的内存地址,而equals比较的是String对象所封装的字符串内容。所以只要用==号来比较String,只要不是自己比自己,那肯定是false。
针对String作为一个基本类型来使用:
- 如果String作为一个基本类型来使用,那么我们视此String对象是
常量池
所拥有的。 - 创建时如果
常量池
内不存在与其指定值相同的字面量,那么此时虚拟机将为此创建新的字面量,并存放在常量池
内。 - 如果
常量池
内存在与其指定值相同的字面量,那么此时虚拟机将不为此创建新的字面量,而直接返回已存在的字面量的引用。
针对String作为一个对象来使用
如果String作为一个对象来使用,那么虚拟机将为此创建一个新的String对象,即为此对象在堆区
中分配空间,并且它并不是常量池
所拥有的,即它是独立的。
延伸:
-
java.lang.String类的对象是一个典型的不可变对象,我们对它进行改变时都不会影响它原来的对象,只会返回一个新构造的字符串对象,这点得类比
StringBuffer
和StringBuilder
,有空再写一篇两者比较的文章 -
字面量:字面量是指由字母,数字等构成的字符串或者数值,它只能作为右值出现。
-
常量和变量都属于变量,只不过常量是赋过值后不能再改变的变量,而普通的变量可以再进行赋值操作。
-
Java中定义常量的方法参考文章csdn
参考
importNew:浅谈Java String内幕(上)
cnblog: 深入理解Java中的String