OOP (Object Oriented Programming)中的身份和平等有什么区别?
答案 0 :(得分:50)
identity:一个变量持有 与另一个变量相同的实例。
相等:两个不同的对象可以 可互换使用。他们经常 拥有相同的身份。
例如:
Integer a = new Integer(1);
Integer b = a;
a
与b
相同。
在Java中,使用==
测试身份。例如,if( a == b )
。
Integer c = new Integer(1);
Integer d = new Integer(1);
c
与d
相同但不相同。
当然,两个相同的变量总是相等的。
答案 1 :(得分:15)
Identity确定两个对象是否共享相同的内存地址。 Equality确定两个对象是否包含相同的状态。
如果两个对象相同,那么它们也是相等的,但仅仅因为两个对象相等而不是意味着它们共享相同的内存地址。
字符串有一个特例,但这不是主题,你需要向其他人询问其工作原理;-)
答案 2 :(得分:5)
Identity表示它是相同的对象实例,而equality表示您比较的对象是对象的不同实例,但碰巧包含相同的数据。
插图(在java中)
Date a = new Date(123);
Date b = new Date(123);
System.out.println(a==b); //false
System.out.println(a.equals(b)); //true
所以a和b是不同的实例(内存中的不同分配),但在“数据”级别上它们是相等的。
答案 3 :(得分:3)
例如,
在StackOverFlow中:
身份:我是迈克尔,你是 sevugarajan,所以我们不一样。
平等:如果我们有相同的声誉 分数,我们在某些方面是平等的。
答案 4 :(得分:2)
在Java和类似语言中“泄漏”对象引用的抽象,您可以测试两个引用是否引用同一个对象。如果它们引用相同的对象,则引用是相同的。在Java中,这是==
运算符。
还有一个equals
方法用于测试两个对象是否具有相同的值,例如当用作HashSet
的键时(相等对象的哈希码也应该相等) )。客户端代码使用时,等同对象应具有相同的“值”和语义。
纯粹的面向对象语言没有身份比较,因为客户端代码通常不应该关心两个对象是否具有相同的内存地址。如果对象代表相同的真实世界实体,那么最好使用一些ID或键值而不是身份建模,然后身份成为等于合同的一部分。不依赖于对象的内存地址来表示真实身份,简化了缓存和分布式行为,并且抑制==
将删除字符串比较中的大量错误或Java中原语装箱的一些用法。
答案 5 :(得分:2)
想想“相同”和“等同”这两个词。如果两件事情是相同的,那么它们具有相同的身份;他们是一回事。如果它们是等价的,则可以替代另一个而不影响结果;它们具有相同的行为和属性。
答案 6 :(得分:1)
身份:对同一对象(o1 == o2
)的两次引用。
平等:方法o1.equals( o2 )
返回true
。这并不一定意味着两个对象包含(全部)相同的数据。
理论上,即使对于相同的对象,也可以覆盖方法equals()
以返回false
。但这会破坏Object.equals()
:
equals方法在非null对象引用上实现等价关系:
- 它是自反的:对于任何非空引用值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。
答案 7 :(得分:1)
相同对象与相等对象
如果表示两个对象的状态在各个方面都是相同的(包括每个级别的OID),则称两个对象具有相同的状态(深度相等)。
如果表示两个对象的状态相同的图(包括所有相应的原子值),则称两个对象具有相同的状态(浅相等)。但是,两个图中的某些对应内部节点可能具有带有不同OID的对象。 示例:此示例说明了比较对象的两个定义之间的区别 平等的国家。
o2 = (i 2 , tuple, <a 1 :i 5 , a 2 :i 6 >)
o3 = (i 3 , tuple, <a 1 :i 4 , a 2 :i 6 >)
o4 = (i 4 , atom, 10)
o5 = (i 5 , atom, 10)
o6 = (i 6 , atom, 20)
在此示例中,对象o1和o2具有相等的状态(浅相等),因为它们在原子级别上的状态相同,但是值通过不同的对象o 4和o 5达到。
但是,对象o1和o3具有相同的状态(深度相等),即使对象本身不是因为它们具有不同的OID也是如此。同样,尽管o4和o5的状态相同,但实际对象o4和o5相等但不相同,因为它们具有不同的OID。
答案 8 :(得分:0)
x == y
和x
引用相同的对象时, y
才为真。
x.equals(y)
取决于x.equals()
的实现,并且通常不如上面那么严格,因为它比较了对象的内容。 (在Java中,如果x.equals(y)
,则x.hashCode() == y.hashCode();
)
示例:
Integer w = new Integer(3);
Integer x = new Integer(1);
Integer y = x;
Integer z = new Integer(1);
// all of these evaluate to true
y.equals(x) // it's the same object, of course the content is same
x.equals(z) // different objects, same content (`1`)
z.equals(y)
!w.equals(x); // the content is different (`3` vs `1`)
!w.equals(y);
!w.equals(z);
x == y // same object
z != x // different objects
y != z
w != x
答案 9 :(得分:0)
For primitive types ( int , boolean , char, long , float ... )
==和!=是相等测试
and for Objects
==和!=是身份测试。 [它仅比较参考文献]
equals
方法用于对象的相等性测试[可以覆盖它以比较特定属性]
我发现了一篇很好的文章 http://www.cs.cornell.edu/courses/cs211/2006sp/Lectures/L14-Comparison/L14cs211sp06.pdf
<强>引用强>
我喜欢猪。狗看着我们。猫看不起我们。猪平等对待我们。:D
Sir Winston Churchill
答案 10 :(得分:0)
身份概念是非常哲学的,这就是为什么你不应该仅仅为了参考而重新考虑它。
如果对第一个的更改反映在第二个上,则可以说两个身份相同,反之亦然。当然,这也包括共享相同的内存地址,但通常在身份与对象的属性相关时,相等性用于检查两个对象何时相同,但这不包括身份。
反之亦然,如果两个项目具有相同的身份,那么它们也是相同的(在可互换的平等条件下)。
答案 11 :(得分:0)
补充一点,identity
也称为 referential
检查(对对象的引用,明白了吗?)和 equality
作为 structural
检查由一些作者。归根结底,内存抽象中的对象只是在特定内存地址索引的映射/表结构。可以有一个或多个引用(内存地址)指向它。它们都是引用上相同的。当同一个对象的内容被复制到另一个副本时,两者在结构上是相等的。