问题代码
代码一
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class vs {
public static void main(String[] args) throws IOException {
String bbb="aaa";
System.out.println(bbb=="aaa"); //true
String str=new vs().getaaa();
System.out.println(str=="aaa"); //false
System.out.println(str.equals("aaa")); //true
}
//通过方法从命令行输入aaa
public String getaaa() throws IOException {
String str="";
BufferedReader strin=new BufferedReader(new InputStreamReader(System.in));
str=strin.readLine();
return str;
}
}
代码二
public class vs {
public static void main(String[] args){
String s1,s2,s3="aaa",s4="aaa";
s1=new String("aaa");
s2=new String("aaa");
System.out.println("s1==s2:"+(s1==s2)); //false
System.out.println("s1==s3:"+(s1==s3)); //false
System.out.println("s3==s4:"+(s3==s4)); //true
System.out.println("s2.equals(s3):"+s2.equals(s3));//true
}
}
问题成因
equals
equals是java.lang.Object类的方法
-
以下为Object类的equals方法源码
public boolean equals(Object obj) { return (this == obj); }
- 参数为Object对象
- 使用==操作符进行判断相等
-
以下为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; }
- 传入参数为Object对象
- 首先使用==操作符进行判断,如果结果为true,则直接返回true,不再进行多余判断
- 如果传入的对象是String类型,将Object对象强制转换为String对象
- 判断两者长度,长度不同直接返回false
- 将两个String的char[]逐字符进行比较,如果发现不同,则返回false
- 若两个String的char[]内容完全一致,则返回true
==
==操作符比较两个变量本身的值,当值为Reference类型时,不会去比较Reference所指向对象的内容,而是直接比较两个Reference的值,而它们内存单元中所存储的数据为内存地址,所以当==运算符两侧为Refesrence时,实际比较的是内存地址。
Tips
两例中均有初始赋值”aaa”的String和一个”aaa”,它们使用==运算符结果为true,是因为它们都是字符串赋值,在Javac编译时,它们两个均指向了常量池中同一个索引,当类被加载到方法区中后,这两个对象所指向的地址也会相同。