测试代码如下
AA aa1=new AA("abc");
AA aa2=new AA("abc");
String string111 = new String("字符串111");
String string222 = new String("字符串111");
String stringing1 = "字符串22222";
String stringing2 = "字符串22222";
System.out.println("类的equals方法:"+aa1.equals(aa2));
System.out.println("类的==方法:"+(aa1==aa2));
System.out.println("new String的equals方法:"+string111.equals(string222));
System.out.println("new String的==方法:"+(string111==string222));
System.out.println("赋值String的equals方法:"+stringing1.equals(stringing2));
System.out.println("赋值String的==方法:"+(stringing1==stringing2));
public class AA {
public String string;
public AA(String string)
{
this.string=string;
}
}
运行结果:
类的equals方法:false
类的方法:false
new String的equals方法:true
new String的方法:false
赋值String的equals方法:true
赋值String的==方法:true
String类和普通类都继承Object类
System.out.println(String.class.getSuperclass().getName());
System.out.println(AA.class.getSuperclass().getName());
运行结果:
java.lang.Object
java.lang.Object
查看三者的equals方法,发现被重写的方法体不同
类的equals方法:
public boolean equals(Object obj) {
return (this == obj);
}
String的equals方法都指向同一个
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String aString = (String)anObject;
if (!COMPACT_STRINGS || this.coder == aString.coder) {
return StringLatin1.equals(value, aString.value);
}
}
return false;
}
结论:
类的equals和==都是比较地址
new String的equals比较值,==比较地址
赋值String如上,比较值/地址
new String的运行结果和赋值String的运行结果不同的原因和Java的堆栈数据结构有关
补充:
new String的对象存放在堆中,当Java编译器遇到关键字new时,每一个对象都在堆中开辟一处内存空间用来存放String对象,数据不共享,所以地址不同。
而局部变量赋值的String存放在栈中,栈的运行效率高,空间小,方法结束后就消失
比如
String string = “字符串”;
String string2 = “字符串”;
string存放在栈中, “字符串” 存放在常量池中
创建string时会在常量池中创建一个“字符串”,然后 string 引用 “字符串” ,在创建string2时先寻找常量池中是否存在 “字符串” ,不存在则重新创建一个,存在就直接引用
注意:虽然他们的地址相同,但当改变string值时,string2的值不会改变,而是重新创建一个“字符串”存放于常量池中