Java Primitives vs. The Rest
Jules
Posted on March 3, 2020
"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.
Posted on March 3, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.