问题:"abcdefg".toLowerCase() == "abcdefg"是true还是false
true
这里首先要注意==和equal()的区别:
对于==来讲,对于基本类型和对于对象来说是不同的,对于基本类型,如果两者的值是相同的,则相同。但是对于浮点数来讲,有以下需要注意的:
对于对象来讲,==相等当且仅当两者都是null(当然是相同的类型)或者指向同一个对象。
而Object类提供了方法equals(),此方法本来也是比较引用是否指向同一个对象的,
public boolean equals(Object obj) {
return (this == obj);
}
然而对于有的类来说,可能有自己逻辑上的相等的概念,而不仅仅是引用的对象是否相同,比如说Integer,当两个数值确实一样,但是是两个对象的时候,我们也希望有一种办法来判定两者在逻辑上是相等的,所以会改写Object的equals函数,
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
有时候我们创建自己的类,也需要进行逻辑比较,比如一个员工类,比较的时候逻辑上比较其员工号即可,因而我们也要改写equals函数,但要注意一下几点:
下面是一个例子:
public class Employee {
String id;
String name;
double salary;
public boolean equals(Object o){
if(this == o)
return true;
if(o instanceof Employee){
Employee other = (Employee)o;
return id.equals(other.getId());
}
return false;
}
public int hashCode() {
return id.hashCode();
}
public String getId(){
return id;
}
}
如下实验可以证实:
Integer int1= new Integer(1);
Integer int2= new Integer(1);
Integer int3=int1; //int3和int1引用同一个对象
System.out.println("int1==int2 is " + (int1==int2));
System.out.println("int1==int3 is " + (int1==int3));
System.out.println("int1 equal int2 is " + (int1.equals(int2)));
System.out.println("int1 equal int3 is " + (int1.equals(int3)));
打印结果如下:
int1==int2 is false
int1==int3 is true
int1 equal int2 is true
int1 equal int3 is true
那如题目中,两个"abcdefg"是同一个对象吗?这就要提到String的一个性质:String常量池的概念。
以""创建的字符串在编译阶段就放在.class的Constant Pool的CONSTANT_String_info结构中。虚拟机中有以下几个区域:方法区,堆,Java栈,程序计数器,本地方法栈。ClassLoader会把Constant Pool加载到方法区中,当""创建的字符串的时候,会到String常量串池中去查找,并返回其地址赋给对象变量。
以new创建的字符串则是运行时在堆中构造的。
所以题目中的两个"abcdefg"是指向同一个地址的,以下可以证明:
String str1 = "abcdefg";
String str2 = "abcdefg";
String str3 = new String("abcdefg");
System.out.println("str1 == str2 is " + (str1 == str2));
System.out.println("str1 equal str2 is " + (str1.equals(str2)));
System.out.println("str1 == str3 is " + (str1 == str3));
System.out.println("str1 equal str3 is " + (str1.equals(str3)));
结果为:
str1 == str2 is true
str1 equal str2 is true
str1 == str3 is false
str1 equal str3 is true
然而本题目中"abcdefg".toLowerCase()按照String的不可改变性,不是应该生成另外一个对象吗?这就要看toLowerCase的实现了:
如果没有任何字符需要改变,return this;
如果做了改变则,return new String(0, count+resultOffset, result);
由此可知"ABCDEF".toLowerCase() == "abcdef"就是false了。
这里还需要提一下的是String的intern函数:它是在常量池中查找String,如果有就返回,没有就添加到常量池。
String str1 = "123";
String str2 = new String("456");
String str3 = (str1 + str2).intern();
String str4 = (str1 + str2).intern();
String str5 = str1 + str2;
String str6 = str1 + str2;
System.out.println(str3 == str4);
System.out.println(str5 == str6);