Hacker News new | ask | show | jobs
by userbinator 4398 days ago
That Java one is particularly amusing, as most programmers otherwise familiar with the language would never know about the integer cache (and their reaction upon discovering that there is one would probably be the same as mine - WTF?)

Edit: I had a feeling I'd heard of an "integer cache" somewhere else" in a WTF-eliciting context... http://thedailywtf.com/Articles/The-Integer-Cache.aspx !

5 comments

It also leads to some interesting programming errors in Java.

    class A {
        public static void main(String[] args) {
            Integer a = 100, b = 100;
            Integer c = 10000, d = 10000;
            System.out.println(a == b);
            System.out.println(c == d);
        }
    }
Prints:

    true
    false
For those unaware, the == check above is doing an Object check (are they the same object). The cache makes the '100' return the same instance of an object. To do actual value checks, you'd need to do c.equals(d)
what a dumb language! operator overloading should have bound the equals method to the == operator without the programmer having to be aware of this. when in java do you ever want to compare if two objects are the same referenced with the same ptr? Never, so why not do the right thing by the user of the language.

At least be consistent between primitives and objectives.

Sadly, I have to use this language daily. My heart belongs to python, but java pays the bills.

You're forgetting legacy and history. Many Java programmers came to Java, myself included, from C (or C++). The == operator in C is a simple register comparison. If you compare two ints the the == operator will return true iff the two int values are the same, but if you compare two int pointers, then equal integer values may or may not be stored at the same address, which is exactly what we're seeing here. Since Java references are pointers, this behavior -- while probably not the right choice -- was less surprising to us, C programmers, than the alternative. Of course, auto-boxing made this behavior even stranger, but autoboxing was added to the language much later.
Python has exactly the same behavior if you compare integers using the is operator. Two int-variables with same value are only "is-equal" up until somewhere around 100000 also. Many beginners do this mistake as they think you should always use is in python and don't even know that == also exist.
Considering the Flyweight is a GoF Design Pattern, and that it talks about doing this specifically for managing integer objects... this shouldn't be a WTF for most people. It's a trick as old as the hills too. Smalltalk has had it going back decades.
It reminds me of a prank a relative of mine used to play on other people using punch-card computers. The computer had no math unit (!) so addition tables and multiplication tables were fed in on punch cards. Easy enough to change one of those and make perfect code give very odd answers.
Boy, he must've been hated, I personally am too young to remember the punch-card days of programming but my dad spent most of his younger days doing it that way and he said that one of the reasons his code has fewer bugs/mistakes than mine (aside from 30+ years exp on me) is because no one wanted to make a stupid mistake somewhere in their stack [of cards] that would mean going to that back of the line just because they used a plus instead of a minus or something (I don't remember the exact example).
The integer cache is well known for over 10 years, presently there is a JVM knob to make it larger: java.lang.Integer.IntegerCache.high So the solution is not surprising at all.

Personally I'd just employ an enhancing classload and replace some of bytecodes ICONST_2 with ICONST_3. (one byte change in the bytecode). Yet, overall uninteresting question.