在我的一次采访中,一位面试官问我:
给定一个Student
类和两个对象s1
和s2
:
s1 = new Student();
s2 = new Student();
s1 == s2
将如何返回true
?
我告诉他把Student
班变成单身班,但他说不,我们必须改变班级级别,这样s1 == s2
才能true
回来。
注意:我们需要更改Student
类。请不要回复s1=s2
。 有什么线索吗?
运算符==
检查两个对象是否相同。 您创建了两个不同的 equals 对象。 所以它们不一样,s1 == s2
会返回 false。 您必须重新定义方法equals
并使用此方法检查它们,如下所示:
s1.equals(s2)
该方法equals
:
指示某个其他对象是否"等于"此对象。
请注意,当您重新定义方法等于时,您还需要重新定义方法哈希代码,如 equals 方法的描述中明确记录的那样:
请注意,每当重写 hashCode 方法时,通常需要重写此方法,以便维护 hashCode 方法的一般协定,该协定声明相等的对象必须具有相等的哈希码。
通常,IDE(如IntelliJ,Eclipse或Netbeans(可以帮助您编写这两种方法的良好实现。
考虑到这一点,我想面试官问了诸如s1 将如何等于 s2谈论它,而您将其误解为s1(simble 等于(s2 将如何。还是他明确地在纸上写了运算符==
?
如果面试官明确询问如何
s1 == s2 // returns true
将两个对象创建为
Student s1 = new Student();
Student s2 = new Student();
唯一的可能性是更改 s1(或 s2(的引用,如下所示:
Student s1 = new Student();
Student s2 = new Student();
s1 = s2; // new added line , or the same if you write s2 == s1
s1 == s2 // now is true
但这是一个技巧,事实上你正在测试两个不同的变量引用同一个对象。
你可以将类似的行为分配给两个变量null
,或者之前创建的另一个Student
。基本上,对分配给s1
相同引用的代码的任何更改都将起作用s2
。
这是一个技巧,但会满足要求:
更改Student
构造函数以抛出一些异常(我选择了一个未经检查的异常,所以我不必在 throws 子句中指定它(:
public Student()
{
throw new NullPointerException();
}
现在,假设我们被允许添加一个 try-catch 块:
Student s1 = null;
Student s2 = null;
try {
s1 = new Student();
s2 = new Student();
}
catch (Exception e) {
}
System.out.println (s1==s2);
这将打印true
,因为s1
和s2
都是null
。
即使我们没有捕获异常,s1 == s2
在两个构造函数调用之后(实际上是在第一个构造函数调用之后,因为第二个永远不会被执行(仍然是正确的,但是我们必须在某个地方捕获异常才能测试它。
正如这里已经回答的那样,==
比较参考。 即它比较s1
和s2
是否指向同一对象。由于您正在使用new
来实例化s1
和s2
,因此您的要求是不可能的。
我看到的唯一合乎逻辑的解决方案是微不足道的:
s1 = new Student();
s2 = new Student();
s1=null;
s2=null;
System.out.println(s1==s2);
或:
s1 = new Student();
s2 = new Student();
s1=s2;
System.out.println(s1==s2);
或:
s1 = new Student();
s2 = new Student();
s2=s1;
System.out.println(s1==s2);
正如@user7评论中所建议的那样
==
比较对象引用时,它会检查两个操作数是否指向同一对象(不是等效的对象,相同的对象(。所以我真的认为唯一的方法可能是这样:
@Override
public Student clone(){
return this;
}
也许这将使==
操作员按照您的要求工作。这对我来说是非常错误的,因为我认为这不是clone()
方法的预期用途。否则,考虑到在课堂上工作的限制,我没有任何其他线索可以按照您的要求制作。
如果不能使用clone()
,也许答案是:不可能这样做。
由于 == 运算符比较对象引用,我认为 s1 和 s2 必须为空。