public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Liulei";
String str3 = str1 + str2;
String str4 = "Hello" + "Liulei";
String str5 = "HelloLiulei";
String str6 = new String("HelloLiulei");
System.out.println(str3 == str4); //false
System.out.println(str3 == str5); //false
System.out.println(str3 == str6); //false
System.out.println(str4 == str5); //true
System.out.println(str4 == str6); //false
System.out.println(str5 == str6); //false
System.out.println(str3.equals(str4)); //true
System.out.println(str3.equals(str5)); //true
System.out.println(str3.equals(str6)); //true
System.out.println(str4.equals(str5)); //true
System.out.println(str4.equals(str6)); //true
System.out.println(str5.equals(str6)); //true
}
*注释为运行结果
==原理分析:
java分为编译时和运行时两种状态
字符串直接赋值是在编译时赋值,并将值存储到字符串常量池(位于jvm存储的方法区中)中.如代码中的str1 str2
在创建str4时,首先java会从常量池中寻找是否存在"Hello"和"Liulei",如果存在,则将这两个字符串拼接(+运算符),如果不存在则新建并将其存储在常量池中
在创建str5时.同str4,同样存储在字符串常量池中,并将该地址指向返回给str5,可知,str4和str5指向同一内存区域
在创建str3时,由于str3赋值右边存在变量,java编译时无法确认变量的准确值(多态),所以str3赋值是在java运行时创建的,并将其存储到堆中(相当于新建一个对象)
在创建str6时,使用new方法直接新建一个string对象,同样保存在堆内存中,并且与str3指向的地址不同
*堆内字符串赋值首先会从字符串常量池查找是否有重复的,如果有,则将将值复制到堆,并返回堆内存储地址
equals分析:
equsla方法是java提供的一个可重写的方法,string重写equals方法源码如下:
public boolean equals(Object anObject){
if(this==anObject){
return true; //判定传入的对象和当前对象是否为同一个对象,如果是就直接返回true.
}
if(anObject instanceof String){ //判定传入的类型值是否为String,若不是则返回false;
String anotherString =(String)anObject;
int n=value.length;
if(n==anotherString.value.length){
char v1[]=value;
char v2[]=anotherString .value;
int i=0;
while(n-- !=0){
if(v1[i] !=v2[i])
return false; //循环对比两个字符串的char[]数组,逐个对比字符是否一致,若存在不一致的情况,则直接返回false;
i++
}
return true; //循环结束都没有找到不匹配的,所以最后返回true;
}
}
return false; //判定传入的String与当前的String的床都是否一致,若不一致就返回false;
}
通过阅读源码理解程序运行结果