解释一下下面的java代码?

classPerson{privateStringname;privateStringidStr;publicPerson(){}publicPerson(Stringn... class Person
{
private String name;
private String idStr;
public Person(){}
public Person(String name , String idStr)
{
this.name = name;
this.idStr = idStr;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
public void setIdStr(String idStr)
{
this.idStr = idStr;
}
public String getIdStr()
{
return this.idStr;
}
public boolean equals(Object obj) ?
{
if (this == obj)
return true;
if (obj != null && obj.getClass() == Person.class)
{
Person personObj = (Person)obj; ?
if (this.getIdStr().equals(personObj.getIdStr()))
{
return true;
}
}
return false;
}
}
public class OverrideEqualsRight
{
public static void main(String[] args)
{
Person p1 = new Person("孙悟空" , "12343433433");
Person p2 = new Person("孙行者" , "12343433433");
Person p3 = new Person("孙悟饭" , "99933433");
// p1和p2的idStr相等,所以输出true
System.out.println("p1和p2是否相等?"
+ p1.equals(p2));
// p2和p3的idStr不相等,所以输出false
System.out.println("p2和p3是否相等?"
+ p2.equals(p3));
}
}
代码中有两处有?的地方我不是很明白:
1 为什么要声明Object obj 不可以是Person obj吗?
2 为什么要强制转换obj的类型呢 不都是Person吗?
展开
 我来答
问题大王java
2015-11-21 · 超过11用户采纳过TA的回答
知道答主
回答量:21
采纳率:0%
帮助的人:17.3万
展开全部
1 为什么要声明Object obj 不可以是Person obj吗?

答:首先,你的equals方法头上应该加上@Override注解,这样才写得标准,表示你的equals方法是覆盖JDK的Object类的equals方法。
其次,如果你的equals方法没有加上@Override注解,表示这个equals方法是你自已写的一个方法,跟JDK的Object类的equals方法毫无关系。那么这种情况下,你把参数写成Person obj是完全正确的,当然后面也不需要强制转换了。不过这样做没有意义,因此我们应该加上@Override注解来表示我们使用的是Object类的equals方法,实际开发中,也必须要加上@Override的。

好,接下来我们讨论的话题建立在“你的equals方法是覆盖JDK的Object类的equals方法”之上:
为什么equals方法的参数是Object obj呢?
第一点、我们从java面向对象的角度来讨论这个问题。因为equals方法是JDK里祖先类Object的其中一个方法,其目的在于比较两个对象是否相同。而世界上的对象千千万万,对应于java代码写出来就是千千万万个不同的类。JDK开发人员怎么知道程序员所定义的类是什么?那么为了让所有对象都能够作为参数传给JDK里的equals方法,JDK的开发人员只能把equals方法的参数设置为Object。否则如果JDK开发人员把参数设置为Person,那你又写了另外一个类叫Student,试问Student类还怎么使用equals方法?
第二点、我们从java语法的角度来讨论这个问题。我们知道,当子类要覆盖父类的方法时,参数类型只能小于或等于父类。那么既然父类的方法参数是Object,则子类必须也要写成Object,而不是写成Person,如果写成Person,则属于语法错误,连编译都不能通过。重写的时候一定要注意equals方法的参数是Object obj类型的引用变量。绝对不可以是其他类型的变量。因为这样的话,和父类Object的equals方法名相同,但是参数列表不同,javac认为是重载。

2 为什么要强制转换obj的类型呢 不都是Person吗?

前面已经提到了,参数必须是Object类型,既然如此,则强转也是必须的。
如果上面我讲的话你能理解,则第2问根本不需要回答你也懂了。
追问
既然子类重写父类的时候 参数类型需要小于或等于父类   Person按说是小于父类的啊?还有就是 if语句不是已经判断两个的类是否一样  为什么还要强制转换呢?我是新手  还有很多不懂   多多原谅哈
追答
对不起,没意思看第二遍,写错了,正确的是:
子类要覆盖父类的方法时,抛出的异常类只能小于或等于父类。而参数类型必须相同,注意,是必须相同。
好,现在你知道为什么参数必须要是Object了吧?接下来继续讨论:
既然参数必须要是Object,那么紧接着if (this == obj)判断的是地址。
注意,这里“不是判断两个的类是否一样 ”而是判断两个对象的内存地址是否相等。
为什么需要写第一个if呢?原因是如果你传递的参数自已本身,那么下面就不需要判断再写代码了,直接return true就搞定。
例如:
p1.equals(p1).
看,equals(p1)的实参是p1,说明他自已跟自已比看是否相同,这当然相同啊,因为是同一个对象。
因此第一个if判断两个对象的内存地址是否相等,如果判断结果是两个对象的内存地址相等,则必定能保证这两个对象就是同一个对象。所以说,第一个if判断是防止你把自已本身这个对象传进去而写的,如果你传的对象就是自已本身,那想都不用想,肯定相等嘛,还需要比吗?所以直接return true就行了,后面的代码不用写了。

至于第二个if判断,则表示:
如果进入第二个if判断,则说明这两个对象不是同一个对象,这种情况下,就要看看这两个对象的属性是否相同了。因此,第二个if语句才是真正判断对象里的内容是否相等。
既然要判断对象里的内容是否相等,则两个对象的类型首先要保持一致。可是方法传递的参数却又限定了是Object,此时【Person personObj = (Person)obj】中的等号左边是Person类型,而等号右边的obj却是Object类型,怎么办?没法比!因为类型不同。

所以这种情况下就转换嘛,把obj强转成Person不就能比了吗?
搞定!
heptnaol
2015-11-21 · TA获得超过7263个赞
知道大有可为答主
回答量:7120
采纳率:78%
帮助的人:1820万
展开全部
两个问题一起回答,我可能这样调用

Monkey m = new Monkey();
boolean eq = p1.equals(m);
因此,1,必须接受任意对象,因此参数是Object
2,和1同理,是任意对象,未必是Person
equals是从Object类就有的方法,override必须保证参数类型一致。
追问
if 语句不是已经判断了是否为同一类型吗
追答
调用者不会这么听话。他可能会拿任意两个Objcet做equals比较
必须得能处理这样的情况。
本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式