首先说明String的equals()方法有两个作用,第一比较引用是否相等,第二,比计较值是否相等。而“==”只能比较引用是否相等。
下面的代码能够帮助我们了解String a=new String()和String a= “string”的区别。
public class StringTest {
public static void main(String[] args) {
String aString=new String("abcd");
String bString=new String("abcd");
System.out.println(aString.equals(aString));【】
System.out.println(aString==bString);
String cString="ddd";
String dString="ddd";
System.out.println(cString.equals(dString));
System.out.println(cString==dString);
}
}
true
false
true
true
常量池可以放字符串常量。当new一个字符串(new String(“abcd”))时,会从常量池获取常量赋值给创建String对象的value字符数组,从而完成一个String对象的创建。即使再new一个值相同的String对象,依旧会再产生一个新对象 ,而不是指向创建好的具有相同值的对象。
String除了new出来之外还可以直接赋值(String cstring="ddd’;)。如果不知道常量池会一脸懵逼。这种赋值方式就是将引用cstring直接指向常量池里的“ddd”存储空间,并不会产生新对象,所以cstring和dstring是两个相等的引用(指向同一对想的引用相等)。
接下来再看下面这样的代码:
for(int i=0;i<100;i++) {
dString+=i;
}
这样的代码会产生过多的垃圾对象,因为String是一个不可变字符序列。
去源码看一下String类的核心。
/** The value is used for character storage. */
private final char value[];
value[] 就是String类的和核心,字符数组value[ ]用来存储String的值。注意value[ ]被final修饰,所以value[ ]是一个常量即被赋值后不可更改。
在上面的循环代码里,dString的值是变了但引用的指向也变了。
用途说明较具体。
在循环中会不断创建新的对象,而引用的指向也不断的变,旧的对象就被抛弃了成了垃圾。严重的化你的程序可能就因为这一段代码崩溃了。