public static void main(String[] args){
String a=new String("aa");
String b=new String("aa");
Person p1=new Person("aa",12);
Person p2=new Person("aa",12);
System.out.println(a.equals(b));
System.out.println(p1.equals(p2));
}为什么第一个结果是true,而第二个是false呢,求大神指点
String a=new String("aa");
String b=new String("aa");
Person p1=new Person("aa",12);
Person p2=new Person("aa",12);
System.out.println(a.equals(b));
System.out.println(p1.equals(p2));
}为什么第一个结果是true,而第二个是false呢,求大神指点
而引用类型的变量就不能用这个了。当比较引用类型变量时,你用==的话,比较的是两个变量是不是同一个对象,如果是同一个对象,则返回true,否则返回false。
比如你的代码:
Person p1=new Person("aa",12);
Person p2=new Person("aa",12);
p1和p2的成员变量一样,但是是两个不同的对象,所以p1==p2返回的就是false。
而equals()是一个方法,是object类的方法。默认的效果和==是一样的,只有两个变量指向同一个对象时,才返回true。
所以你直接使用 System.out.println(p1.equals(p2));,输出的是false。
而String类(字符串)重写了equlas()方法(希望你学到了继承方面的知识)。
但是你的Person类应该没有重写这个方法,直接是默认的,肯定返回的是默认的!
public boolean equals(Object obj) {
return (this == obj);
}
String的equal
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;
}
对于基本类型来说,内存中存储的是实际数值
对于引用类型来说,内存中存诸的是对象的地址(每new一次新的对象,就会在新的地址存储这个对象)equals是按equals方法来比较的,如果没有重写equals方法,则参照父类的equals方法
对于String对象也适用于上述规则,但要注意String有个常量池,有时候会重用常量池的对象,以至于某些情况下==会返回true
参照这个问题中我的回答:
https://bbs.csdn.net/topics/392391937
而Person类应该是你自定义的类,如果自定义类中没有重写equals()方法,默认调用equals()方法,比较的是对象引用,这个时候,equals()方法和“==”功能一样。
明显,p1,p2是两个不同的对象,所以,p1.equals(p2) = false。这里,p1 == p2也是返回false。
https://img-blog.csdn.net/20180504150042541?water/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xlZ2VuZGFyeWhhaGE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70
第一个输出了true,第二个输出false,我们都知道引用数据类型时“==”比较对象时比较的不是内容而是引用,但因为在java中早就封装好-128到127之间的数字了,所以当数字介于它们之间时,就不会new新的对象了,而是之间引用常量池中的Integer对象。
第一个可以认为是在内存中指向同一个内存空间。如 你上面的第一个;
第二个可以这么认为 一个张三 一个李四 他们都是12岁 。他们是同一个人吗。你觉得。
== 操作符比较的是两个对象是否相同,而equals其实是一个方法,比较内容是否一样为什么楼主的代码结果会那样,因为:
1、equals 方法其实是在 Object 类中定义的,它有一个默认的实现,只是简单点进行 == 比较:public boolean equals(Object obj) {
return (this == obj);
}
2、而 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;
}
@Override
public boolean equals(Object other){
if(other == null)
return false;
if(other instanceof Person){
Person p1 = (Person)other;
if(this.name != null){
if(this.name.equals(p2.name) == false) return false;
}else {
if(p1.name != null) return false;
}
......
}else{
return false;
}
}
== 操作符比较的是两个对象是否相同,而equals其实是一个方法,比较内容是否一样
String b=new String("aa");
同学你好,这是堆栈之间的动态分配,我看能不能画图给你
首先string类型是一个引用数据类型,一旦声明,就在栈里有个引用类型的a,如果new出来一个实例化对象,堆里面就会自动分配一个内存空间用于存放字符串"aa". 于是引用类型的a就指向堆里面的字符串"aa". (下面的字符型b也这样理解)。
equals本身比较 就是java中的一个方法,它先比较地址再比较内容,而"等于"在字符型比较的是地址 地址一样则直接返回true,不一样再比较字符串内容 一样返回true。
由此可得: 你这两行代码内容就是在堆里开辟了两个内容空间且对应在栈里的地址也不一样,
但是你使用的是equals比较 可见在堆里的内存空间里的内容相等所以结果是-----------true。
,equals是两个字符串之间的比较,所以第一个是true
我猜想,如果楼主知道是怎么实现的,就不来这里问了。下面是具体解释:
第一个是字符串的比较,在jdk源码中重写了equals方法,
比较的是两个字符串是否一样,所以返回true。
=====具体为什么会是一样的字符串,涉及到JVM对字符串的处理。有兴趣可以看一下。第二个是Person的比较,因为没有在person里面更改equals方法,
默认比较的是地址,两个新生成的对象物理地址肯定不一样,所以为false。
=====楼主可以直接System.out.println(p1);System.out.println(p2);这两个是不一样的哦~如果还是不理解,可以这么理解:
String a=new String("张伟");
String b=new String("张伟");
Person p1=new Person("张伟",12);
Person p2=new Person("张伟",12);
中国叫张伟的人那么多,名字都是一样的~~
p1和p2虽然名字都是叫张伟,但是肯定不是一个人啊,对不对?
但是你用这个来比较对象的时候,需要对方法进行重写
==是用来比较地址的
而第二个person对象,你如果没有重写hashCode和equals方法,默认比较的地址,而new person对象的地址是不同的,所以返回false,
equalspublic boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”。 equals 方法在非空对象引用上实现相等关系: 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
对于任何非空引用值 x,x.equals(null) 都应返回 false。 Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。 注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。 参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。
还有String 类的api的equals 方法:只要他们的值相同就返回true 望采纳
equalspublic boolean equals(Object anObject) 将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。 覆盖:
类 Object 中的 equals 参数:
anObject - 与此 String 进行比较的对象。
返回:
如果给定对象表示的 String 与此 String 相等,则返回 true;否则返回 false。
另请参见:
compareTo(String), equalsIgnoreCase(String)
这2个String里的字符串相同 应该是都在字符串常量池里吧。。直接在双引号里的 才在字符串常量池
额 我看错了。。我看成String str=“aa”了 没注意,他是new了一下
java对象实际上和C或C++的指针类似,都是属于引用类型。
另外,所说的==和equals是不一样的。equals往往比较的是字符串的值是否相等,而==比较的是值的大小(注意,是值,如果是java对象比较,那么就是java对象的地址所在值,你有空看下jvm的相关知识,就清楚java的存储方式了。)
String a=new String("aa");
String b=new String("aa");
Person p1=new Person("aa",12);
Person p2=new Person("aa",12);
System.out.println(a.equals(b));
System.out.println(p1.equals(p2));
}第一个结果是true,是因为 String 类 重写了Object类的 equals()方法 比较的是两个对象的内容是否相同
而第二个是false 是因为Person类创建的时候没有重写Object类的equals()方法 在底层中还是用==来比较两个地址引用是否相等 由于new了两个对象,所以他们的地址肯定是不相等的。
equals 不重写的话也是比较首地址
因为String 等java提供的类都重写了equals方法 所以他们比较的是内容是否相同
引用类型equals比较也是他们在计算机中的地址,但当你比较的是对象时,你
必须重写equals,不然比较的就是对象中第一个属性在计算机中存放的地址。
String比较特殊,它的equals比较的是你看到的值,因为它已经重写了equals。