User Tools

Site Tools


Sidebar

Dave Orme muses about agile and functional programming.

My current work emphasizes SOA applications using Scala, Kubernetes, and AWS with a React-based SPA front-end. I'm also interested in progressive web applications and developer tools.


Blog

Scala, Clojure, and FP

Agile

The Cloud

Data-First Development

Older work

Coconut Palm Software home


Donate Bitcoin:

1Ecnr9vtkC8b9FvmQjQaJ9ZsHB127UzVD6

Keywords:

Kubernetes, Docker, Streaming Data, Spark, Scala, Clojure, OSGi, Karaf, GCP, AWS, SQL

Disclaimer:

Everything I say here is my own opinion and not necessarily that of my employer.

blog:in_java_5_0_is_not_always_equal_to_0

In Java 5, 0 is not always equal to 0

Much to my surprise yesterday, I discovered that Java 5 believes that 0 != 0 in certain situations.

Try the following in Java 5:

System.out.println(0L == 0);
System.out.println(((Long)0L).equals(0));

For me, this prints:

true
false

A little more investigation yields the following implementation in class Long:

public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}

So, because I'm comparing a boxed Integer with a boxed Long, 0 isn't equal to itself. But if I work with unboxed types, they behave the way I expect.

Mathematically speaking, this behavior of course is absolutely broken. 0 is always 0, no matter what the binary representation. In addition, one could argue that this violates at least the spirit of the API contract for equals:

/**
 * It is reflexive: for any non-null reference value
 *     x, x.equals(x) should return
 *     true.
 * ....
 */

I understand that technically Integer(0) and Long(0) aren't the same thing. However, as an object oriented abstraction, they are certainly intended to represent exactly the same value.

Mathematically speaking, Integer(0) and Long(0) both represent the number zero with exactly the same amount of precision. Mathematical precision for the Integer 0 is the same regardless of the number of binary 0s there are, so in no sense is there ever any round-off error for binary zero, no matter the representation.

Consequently, it would seem to make much more sense for Integer(0) and Long(0L), and by analogy, Float(0.0f) and Double(0.0) to be treated by the language as exactly the same number. Similarly, it seems that the pairs (Integer(0) and 0) and (Long(0L) and 0L) should have interchangeable semantics–especially in a language where autoboxing can automagically convert 0 to Integer(0) and Long(0) to 0L and back.

At a minimum, this behavior certainly violates the principle of least surprise. Maybe there's a good reason for this, but I can't think of one right now.

If there is a good reason, perhaps someone could help me to understand it?

~~LINKBACK~~ ~~DISCUSSION:closed~~

blog/in_java_5_0_is_not_always_equal_to_0.txt · Last modified: 2014/10/17 22:08 (external edit)