-
String使用+进行拼接时的变化
public class StringCompare {
public static void main(String []args){
String n1 = "123";
String n2 = "1234";
n1 = n1 +"4";
System.out.println(n2 == n1 );
System.out.println(n2.equals(n1) );
}
}
结果:
false
true
因为使用==进行比较两个对象的时候是,对String 引用的地址对象进行比较,而equals方法是通过对Object的equals的方法进行重写,在比较多的时候是对String的值进行比较的所以第一个比较时FALSE,第二个是true
通过程序的debug模式可以查看n1和n2两个栈的引用变化
可以看到此时n1的引用指向的地址是@467
此时n2的引用指向的地址是@468
当使用+进行字符串拼接的时候n1的指向地址是@470
由此可知在Java中String 的拼接操作实质和String.concat相似
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
int len = value.length;
char buf[] = Arrays.copyOf(value, len + otherLen);
str.getChars(buf, len);
return new String(buf, true);
}
在jvm虚拟机中存在栈、堆、字符串常量池(存储字符串常量对象)
a、通常String n1 = "123";进行赋值的时候,运行的过程是首先jvm虚拟机会去字符串常量池查询是否存在"123"值得这个String对象,当不存在的时候会在常量池中new String("123")这个对象并且将其地址引用给n1,当存在的时候会直接将其地址引用给n1,并且以上操作是在文件编译的时候就已经完成的
b、String n3 = new String("123");在jvm中的操作是:在程序只有运行到这一步的时候才会产生内存的变化其变化的过程主要存在两个阶段的。第一个阶段是,在jvm虚拟机的栈和堆首先会分配两个空间,一个是栈空间n3,一个new String("123")对象空间。第二阶段是new String("123")空间存储的是String对象,而String对象在jvm存储中通常时候存放在字符串常量池的,因为jvm虚拟机首先会去查询常量池中是否存在"123"的,当存在的时候会将其地址赋值给new String("123"),因此new String("123")堆中存放的是常量池中的"123"的地址引用