我们可以通过覆盖相应类中的equals / hashcode方法来比较两个对象,但是,这两个对象在我们的编写方法(equals / hashcode)的上下文中将是相同的!
即使我们发现这两个对象具有相同的所有属性值,这是否真的意味着什么呢?我的意思是,根据编译器/ JVM,这两个将是不同的对象,对吧?我想他们也会拥有两个不同的记忆位置,不是吗?
(我是Java的新手,所以如果我说了一些非常愚蠢的话,我会很感激,如果你能纠正我。或者如果你需要明确任何事情,请随意提问。但鉴于此事实上,我要求所有请不要让我完全改变我的问题或结构。提前致谢!)
答案 0 :(得分:0)
在理论上是的,它并不重要,但是对于你编写的所有应用程序来说并不是这样吗?但每当我比较一个对象时,我知道它引用了相同的数据库记录,因为ID是相同的(和类型),它对我的代码很有价值。例如,您可以确保您的对象不在列表中,您可以在列表中有两个不同的实例,而您需要一个数据库对象的唯一表示列表,那么.equals函数将变得有用。
如果你需要知道它是否是完全相同的实例,你可能不应该覆盖.equals方法。像其他人说的那样重要的是两个包含相同文本值的字符串,例如:
function foo() {
String bar = "I'm cool";
String baz = "I'm cool";
assertTrue(bar.equals(baz)); //true
assertTrue(bar == baz); //false
}
示例可能有误,但这是不同之处。如果重写equals方法对JVM无关紧要,那么JVM就没有良心。
玩得开心!
答案 1 :(得分:0)
你的问题太多混乱,缺乏连贯性。你写道:
不,你不是。在执行某些操作时比较两个对象,例如:我们可以通过覆盖相应类
中的equals / hashcode方法来比较两个对象
String firstString = "asdf";
int result = firstString.compareTo("asdff");
你"比较"当您在实现compareTo
(Comparable
)的类的对象上调用firstString
方法时,将另一个对象("asdff"
)作为方法的实际参数传递。这就是它,它只是一个名称问题(类型的名称 - 类 - 以及方法的名称)。
关于等式运算符(==)和equals方法之间的区别,同样,它只是定义的问题。规则在此处定义https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.21
即使我们发现这两个对象具有相同的所有属性值,这是否真的意味着什么呢?
有什么对象?这些物体是什么类型的?他们的属性是什么类型的?这一切都取决于它们的实施方式。这个问题非常暧昧,但无论如何我都会说答案是否定的。在Java程序(或任何其他语言)的上下文中,平等并不意味着超出语言规范和代码定义的任何内容。
我想他们也会拥有两个不同的记忆位置,不是吗?
示例(如果您不理解"断言"事情,请检查JUnit。它只是意味着"这必须是真/假"):
@Test
public void testCrazy()
{
Object firstObject = new Object();
// now I have a reference on the stack (firstObject) that points to some memory
// location on the heap that holds some bytes representing an Object instance
Object secondObject = new Object();
// now I have another reference pointing to a DIFFERENT location on the
// heap
boolean equalReferences = (firstObject == secondObject);
// equalReferences is expected to be false
assertFalse(equalReferences);
// look, I make the first reference point to the locations held by the
// second one (tha is what = does if applied to references)
firstObject = secondObject;
// now the 2 references are expected to pass the equality operator test
assertTrue(firstObject == secondObject);
// what if I override equals in a completely nonsense way?
firstObject = new Object(){
@Override
public boolean equals(Object obj)
{
// no matter what, it always returns false.
// does it make sense? Probably not in our common sense, but the
// compiler won't complain
return false;
}
};
secondObject = firstObject;
// now they do point to same same memory location, in fact
assertTrue(secondObject == firstObject);
// but if I call the overriden equals method:
assertFalse(firstObject.equals(secondObject));
// it is still failing even if I call equals on firstObject itself:
assertFalse(firstObject.equals(firstObject));
}