1

Is there any strong reason to use short instead of int in a 64bits JVM?

I mean, both will take 32bits of memory allocated.

This topics shows how Integer can be faster for operations, like multiplication: [In java, is it more efficient to use byte or short instead of int and float instead of double?

I also know that Array of primitives are preferable for saving memory allocated.

Besides that, is there anything else to take into consideration at time to chose between these two types?

  • 1
    Are you talking about `Integer` and `Short` objects or about `short` and `int` primitive values? You are not using them consistently. – Holger Jan 11 '19 at 16:48

1 Answers1

2

tl;dr

Unless you have a very special use-case, just use:

  • Integer for business object values, member variables on a class.
  • int for large amounts of raw data.

Just use Integer

For most common business-oriented Java apps, common practice is to just use the 32-bit int or Integer without much further thought, unless you know you will have values over 2 billion in which case use long or Long. On modern conventional hardware, there is little reason to fret over using short/Short.

Special cases

But since you asked “is there anything else to take into consideration at time to chose”, here are three special cases: enforcing limits, porting C code, and alternative hardware.

Enforce limit

If you want to enforce the limits of a short or Short, use those types. Choose these when you know you should have only values less than approximately 32,000, and want the compiler or runtime JVM to enforce that.

For example, add one to 101:

short oneOhOnePlusOne = ( (short) 101 + (short) 1 ) ;
System.out.println( "oneOhOnePlusOne: " + oneOhOnePlusOne ) ;

102

Next, try to exceed the limit to see the compiler enforce the limit.

short shortMaxPlusOne = ( Short.MAX_VALUE + (short) 1 ) ;
System.out.println( "shortMaxPlusOne: " + shortMaxPlusOne ) ;

error: incompatible types: possible lossy conversion from int to short

See this code run live at IdeOne.com.

Porting C code

These various numeric types were likely put in Java to make easier to port C code, easier both both practically and psychologically. The inventors of Java were well aware that during that era most every attempt at a new programming language failed with the criticism that it was “not like C”. Thus Objective-C (an inspiration for Java), and thus the monstrosity that is C++.

So, indeed, if you are porting C code, use the matching type to replicate behavior.

By the way… Technically, C does not actually define the size of its numeric types. In practice virtually every implementation of C uses the sizes as seen in Java.

FYI, even the most modern languages such as Swift and Kotlin have built-in numeric types for 8, 16, 32, and 64 bit integers.

More restrictive hardware

If there is any chance your app might run on other hardware not based on x86-64, then you may want to use these types. Alternate implementations of Java for such hardware might optimize better for the smaller types.

Primitive versus Object

Array of primitives are preferable for saving memory allocated

First of all, don't stress out on this. Don't fall into the trap of premature optimization. On conventional hardware with most common apps, any savings of memory on using primitives versus objects and arrays versus collections will be insignificant. Use the type (primitive/object) and structure (array/collection) appropriate to your coding context.

My practice:

  • In my code, objects.
    Use only objects (Integer, not int) within my own classes. I have two reasons. Firstly, I am among the camp of Object fans that wish Java were pure OOP without any primitives. (Indeed, there is research ongoing to see if primitives can virtually disappear in far-future versions of Java.) Secondly, I find when I used a primitive, I end up needing to use it in a context demanding objects, such as with collections.
  • With others’ code, use primitives if they do.
    Outside my own classes, I do not force the issue, as undue auto-boxing is senseless. If external code (not my own) is using primitives, I use primitives in that context.
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • 1
    @Thilo I lifted your text for a `tl;dr` up top. Thanks. – Basil Bourque Jan 12 '19 at 03:55
  • @Thilo since OP has touched "arrays" in his question, an array of `int` and array of `Integer` might have actually a bigger impact than it seems; like reading a pdf as a byte array for example. Each `Byte` would add an extra `24 bytes`, for a pdf that matters; otherwise would have to agree with you. – Eugene Jan 13 '19 at 13:35
  • @Eugene I expanded the tl;dr section per your comment. – Basil Bourque Jan 13 '19 at 19:07
  • @Thilo bulk data processing in general, is the domain of primitive data, regardless of whether the library deals with `byte[]`, `ByteBuffer`, `InputStream`/`OutputStream`, or an `IntStream`. I don’t think that there is a point in calling them all “special cases”. And, I still don’t get it. Even if we assume that there is no relevant performance difference in our case, why should I ever use `Integer`, which is longer, need the shift key while typing, and requires me to think about whether it could be `null`? Why should I use “`Integer` for business values”? I’ve seen not a single reason here. – Holger Jan 14 '19 at 12:42
  • @Holger we use it, unfortunately. our team decided that `null` is really "not written yet", since `int` can be zero by default and zero has a business value in our case. I admit that it could have been done in a better way, but that was a TODO that was carried for years and never done – Eugene Jan 14 '19 at 12:49
  • @Eugene that’s what I call the special case… But you can postpone your TODO until Java has genuine support for nullable primitive types like `int?` or such. – Holger Jan 14 '19 at 12:57