Java中String类型具有一个equals的方法可以用于判断两种字符串是否相等,但是这种相等又与运算符==所判断的“相等”有所不同,接下来进行分析,结论由程序进行验证
String的equals函数只要两个字符串“看起来”相等,就可以返回true,“看起来”相等意思指的是,当两个字符串对象所存放的内容相同时,不需要存放的内存地址相同,但是==判断则只有当判断的两个变量所使用的内存地址为相同时才返回true。例如有两个长得一模一样的双胞胎A,B,若使用A==B来判断会返回false,使用A.equals(B)则会返回true。
我们可以看object中的equals函数的源码为
public boolean equals(Object obj) { return (this == obj); }
既然如此,那String的equals与==为什么会不一样呢,这里我们要看一下String中重写equals的源码:
public boolean equals(Object anObject) { if (this == anObject) { return true; } 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; }可以看出String中的equals函数首先判断其内存地址是否为同一个:
if (this == anObject) { return true; }
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; } }
public class StringTest01 { public static void main(String[] args) { // TODO Auto-generated method stub String hello="hello"; String hel1=hello; String hel2="hel"; String hel3=hel2+"lo"; String hel4=hel2.concat("lo"); System.out.println(hello); System.out.println(hel1); System.out.println(hel3); System.out.println(hel4); //==等号测试 System.out.println(hello==hel1); System.out.println(hello==hel3); System.out.println(hello==hel4); System.out.println(hel3==hel4); //equals函数测试 System.out.println(hello.equals(hel1)); System.out.println(hello.equals(hel3)); System.out.println(hello.equals(hel4)); System.out.println(hel3.equals(hel4)); //StringBuilder测试 StringBuilder helloBuilder = new StringBuilder("hel"); System.out.println(helloBuilder.equals(hel2)); } }
最后一个StringBuilder的测试我们发现虽然使用equals来判断,但是返回的是false,这是为什么呢?
首先,当我们使用StringBuilder创建对象时,肯定会在内存中开辟一个新的专属的地址用于存放对象内容,但是即使StringBuilder中存放的内容与其他字符串的内容相同,使用equals来判断也是返回false,这是因为StringBuilder并没有重写equals函数,即StringBuilder的equals为:
public boolean equals(Object obj) { return (this == obj); }所以会返回false。