首先几个知识点:
我们知道String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,而String的equals方法比较的是对象的值。
基本数据类型==比较的是值,引用数据类型==比较的是内存地址。
String类中的equals()方法源码:
public boolean equals(Object anObject) {
//如果是同一个对象
if (this == anObject) {
return true;
}
//如果传递进来的参数是String类的实例
if (anObject instanceof String) {
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;
i++;
}
return true;
}
}
return false;
}
现在大概有了一些了解和认识,再看下下面的知识点
final只对引用的"值"(即内存地址)有效,迫使引用只能指向初始化指向的那个对象;通俗的说就是final String 修饰的 字符串常量不可再改变其引用。
例子1:
分析: JVM对于字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的" + "连接优化为连接后的值,拿"a"+ 1来说,经编译器优化后在class中就E经是a1。在编译期其字符串常量的值就确定下来,故.上面程序最终的结果都为true。
分析: JVM对于字符串引用,由于在字符串的" + "连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a"+ bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。
分析:和[3]中唯一不同的是bb字符串加了 final修饰,对于final修饰的变量, 它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。
所以此时的"a" + bb和"a"+ "b"效果是一样的。故上面程序的结果为true。
再看个实例,来帮助加深理解:
public class Demo {
public static void main(String[] args) {
String a="a";
final String b = "b";
String ab1 = "ab";
System.out.println(System.identityHashCode(ab1)); //输出HashCode码
String ab2 = a + b;
//反编译代码 String ab2 = (new StringBuilder()).append(a).append("b").toString();
System.out.println(System.identityHashCode(ab2));
String ab3 = a + "b";
//反编译代码 String ab3 = (new StringBuilder()).append(a).append("b").toString();
System.out.println(System.identityHashCode(ab3));
String ab4 = "a" + b;
System.out.println(System.identityHashCode(ab4));
System.out.println("----------------");
System.out.println(ab1 == ab2); //false
System.out.println(ab1 == ab3); //false
System.out.println(ab2 == ab3); //false
System.out.println(ab1 == ab4); //true
System.out.println(ab2 == ab4); //false
System.out.println(ab3 == ab4); //false
System.out.println("-------------------");
System.out.println(ab1.equals(ab2));//true
System.out.println(ab1.equals(ab3));//true
System.out.println(ab2.equals(ab3));//true
System.out.println(ab1.equals(ab4));//true
System.out.println(ab2.equals(ab4));//true
System.out.println(ab3.equals(ab4));//true
System.out.println("-------------------");
System.out.println(ab1.hashCode());
System.out.println(ab2.hashCode());
System.out.println(ab3.hashCode());
System.out.println(ab4.hashCode());
}
}
其对应输出结果:
//输出结果如下:
356573597
1735600054
21685669
356573597
----------------
false
false
false
true
false
false
-------------------
true
true
true
true
true
true
-------------------
3105
3105
3105
3105