是否存在传递法不能成立的对象或原始类型;例如
A == B,B == C但A!= B
我不是在谈论equals()方法。我对==操作
感兴趣我们可以证明这一点吗?
答案 0 :(得分:9)
你走了。 A==B
和B==C
会导致Float
升级为浮动,因此==
返回true。但是,A==C
是引用相等,这是错误的。
Float A = new Float(1.0f);
float B = 1.0f;
Float C = new Float(1.0f);
System.out.println(A==B);
System.out.println(B==C);
System.out.println(A==C);
Float
在这里并不特别,它可以很容易Integer
或Boolean
。
以下是语言规范中的相关部分:
15.21.1。数值等式算子==和!=
如果等于运算符的操作数都是数字类型,或者 一个是数字类型,另一个是可转换的(§5.1.8) 数字类型,对操作数执行二进制数字提升 (§5.6.2)。
和
15.21.3。参考等式运算符==和!=
如果相等运算符的操作数都是引用 type或null类型,则操作是对象相等。
这是第二个反例,这次是使用long
和float
进行比较的事实,使用float
比较。
long a = 99999999999999L;
float b = 99999999999999.0f;
long c = 99999999999998L;
System.out.println(a==b);
System.out.println(b==c);
System.out.println(a==c);
第三,我认为即使A,B和C属于同一类型,理论上也存在非传递性存在。
如果A和C是double-extended-exponent values(与它们的最接近的两倍具有相同的值B),那么当计算A == B和B == C时,语言实现可以选择舍入A和C到它们最接近的双精度值(即B)。当执行A == C时,它可以同样选择 not 来舍入。比较必须在未标记为FP-strict
的上下文中完成基本上“5.1.13。值集转换”为Java提供了一个有限的实现定义的非FP严格浮点/双精度计算行为,这可以用来(至少在理论上)找到一个反...平等传递的例子。
答案 1 :(得分:1)
Swift给出了一个非常奇怪的例子。而不是参考语义在发挥作用,嵌套的可选内容已被包装的程度以及编译器显式解开该可选内容的程度将发挥作用:
let a = nil as Int? as Int?? as? Int?
let b = nil as Int? as Int??
let c: Int? = nil
assert(b == a) // passes
assert(c == a && c == nil && a != nil) // passes. wtf
assert(c == b && u == nil && b != nil) // passes. wtf