DEV Community

Jules Roadknight
Jules Roadknight

Posted on

Java Primitives vs. The Rest

"Friends don't let friends use Integer."

Related to my last post about not making everything static and recursing through chained methods, a colleague offered the above maxim. And, also related, it was something low priority, but on my radar to look up when I had more time (because that's going to happen). The final connection was that I was once again making things harder for myself by using the wrong tool for the job.

Why were you using Integer Jules?

Because I didn't know about the primitive int. These distinctions don't exist in Ruby, so they didn't exist to me. Somebody had pointed out that using Integer would create issues, but it became an afterthought because it was 'working' now.

So what's the difference?

Integer five = 5;

Integer is an object reference. When I declare five as an Integer, I'm making a new object, with a value of 5, that I am passing by reference whenever I refer to five.

int five = 5;

The int type is a primitive, which stores an actual value, instead of the reference to an object where the value is stored. This means slightly better performance when using primitives.

Does it really make a difference?

An excerpt from Joshua Bloch's Effective Java gives the following example:

Example 1

public static void main(String[] args) {
    Long sum = 0L; // uses Long, not long
    for (long i = 0; i <= Integer.MAX_VALUE; i++) {
        sum += i;
    }
    System.out.println(sum);
}

The above code takes 43 seconds to run because reference type Long is used. If you replace Long with long, it takes 6.8 seconds. Think of all of the objects you're creating just to refer to once.

Example 2

Integer x = 1;
Integer y = 1;
return x == y; // false

int a = 1;
int b = 1;
return a == b; // true

If using reference types, you end up comparing objects instead of values unless .equals() is used.

So why use reference types?

Reference types let you work with useful methods like Map, List, and Set (pretty much any class method), which require an object. Objects like Integer also allow for null values, should you need them.

The important thing is to consider your needs, such as whether your program is going to require the option to use null with numbers, or whether you need to use certain class methods. Many class methods could be replicated to work with primitives if necessary, but you have options both with and without as it is.

In summary, you have high-performance options in primitives, and options with greater functionality in reference types.

More principles please

It's easy to get so caught up in small details that you miss the big ideas, so I've found immense value already in the simplicity of "Friends don't let friends use Integer", and the more rounded "Only use Integer where int can't do the job" that has emerged from doing some research.

I suppose that another good principle here is "Read the docs" as somebody already considered that it might be useful to have a basic understanding of the language so yeah, I'm going to go and read the docs over at https://docs.oracle.com/javase/tutorial/java/nutsandbolts/

Anyway, thanks for reading, and if you've got anything to add I'd love to hear it!

P.S.

Extra Note Regarding Ruby

The addition of new kinds of variables is not just helping me work with Java, but is also giving me insight into the kind of tradeoffs that you might make when working with a language like Ruby. In benchmark tests, Ruby is always near the bottom, and it's easy to see why when every bit of data is an object. But it is very nice to work with.

Discussion (0)