views:

352

answers:

9

In which case should you use primitive types(int) or reference types (Integer)?

This question sparked my curiosity.

+5  A: 

That really depends on the context. First prefer the primitive, because it's more intuitive and has less overhead. If it is not possible for generics/autoboxing reasons, or if you want it to be nullable, then go for the wrapper type (complex type as you call it).

BalusC
Another point to be considered is whether you need to differentiate between no value (null) and zero.
Chandru
@Chandru: Yes, that's already covered by "nullable" :)
BalusC
+1  A: 

Since Java does something called auto-boxing and auto-unboxing, you should use the primitive type int in most cases because of less overhead.

The only time you absolutely need to use Integer is in generics.

List<int> list; // won't compile
List<Integer> list; // correct
jjnguy
Well, and when trying to use primitive types where objects are expected.
Joey
A: 

I dont think there is any rule as such. I would choose the types over primitives (Integer over int) when I write method signatures, Maps, collections, Data Objects that get passed around. As such I would still like to use Integer instead of int even inside of methods etc. But if you think that is too much trouble (to type extra "eger") then it is okay to use ints for local variables.

Calm Storm
+1  A: 

Rather than calling them "complex types", you'd be best served thinking Integer, Double, etc. as "Classes", and int, double, etc. as "primitives".

If you're doing any type of sophisticated math, the Class-based numeric representation like Integer and Double will be cumbersome and slow you down - many math operations can only be done with primitives.

On the other hand, if you're trying to put your numbers into collections like Lists and Maps, those collections can only contain objects - and thus you must use (or convert to) classes like Integer and Double.

Personally, I use primitives whenever I can get away with it, and only convert to the Class representations like Integer when it's time to do input or output, and the transport requires those representations.

However, if you aren't doing any math at all, and instead are just passing the values straight through your code, you might save yourself some trouble by dealing with the Class-based forms (like Integer) exclusively.

Glenn Barnett
A: 

If you want to setAttribute to session you have to use Object like Integer,Boolean,String in servlets. If you want to use value you can use primitive types. Objects may be null but primitives not. And if you want to compare types for primitives use == but objects use .equals because in object comparision == looks not values it looks if these are the same objects. And using primitives makes faster the code.

A: 

One case in which Integer might be prefered is when you are working with a database where numerical entries are allowed to be null, since you wouldn't be able to represent a null value with an int.

But of course if you're doing straight math, then int would be better as others have mentioned due to intuitiveness and less overhead.

FromCanada
+1  A: 

The general rules I follow when creating an API can be summarized as follows:

  1. If the method must return an value, use a primitive type
  2. If the method may not always apply (eg: getRadioId(...) on an object where such an ID may not exist), then return an Integer and specify in the JavaDocs that the method will return null in some cases.

On #2, look out for NPEs when autoboxing. If you have a method defined as:

public Integer getValue();

And then call it as follows:

int myValue = getValue();

In the case where getValue() returns null you'll get an NPE without an obvious cause.

Jason Nichols
+2  A: 

In which case should you use primitive types(int) or reference types (Integer)?

As a rule of thumb, I will use a primitive (such as int) unless I have to use a class that wraps a primitive.

One of the cases were one must use a wrapper class such as Integer is in the case of using generics, as Java does not support the use of primitive types as type parameters:

List<int> intList = new ArrayList<int>();               // Not allowed.
List<Integer> integerList = new ArrayList<Integer>();   // Allowed.

And, in many cases, I will take advantage of autoboxing and unboxing, so I don't have to explicitly perform conversions from primitives to its wrapper class and vice versa:

// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3); 

int sum = 0;

// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
  sum += number;
}

Also, as an additional note, when converting from primitives to its wrapper class objects, and unique instances of objects are not necessary, use the valueOf method provided by the wrapper method, as it performs caching and return the same instance for a certain value, reducing the number of objects which are created:

Integer i1 = Integer.valueOf(1);   // Prefer this.
Integer i2 = new Integer(1);       // Avoid if not necessary.

For more information on the valueOf methods, the API specification for the Integer.valueOf method can serve as a reference for how those methods will behave in the wrapper classes for primitives.

coobird
+1  A: 

My rule of thumb is: use boxed primitives only when it's necessary to get the code to compile. The only places in your code where the names of the primitive wrapper classes should appear is in generic type parameters and static method calls:

List<Integer> intList = new ArrayList<Integer>();

int n = Integer.parseInt("123");

That's the advice I would give to new Java programmers. As they learn more, they'll run into situations where they have to be more discerning, like when dealing with Maps or databases, but by then they should also have a better understanding of the difference between primitives and boxed primitives.

Autoboxing tempts us to believe int and Integer (for example) are interchangeable, but it's a trap. If you mix the two kinds of value indiscriminately, you can end up comparing two Integer values with == or trying to unbox a null without realizing it. The resulting bugs can be intermittent and difficult to track down.

It doesn't help that comparing boxed primitives with == sometimes works as if it were doing a value comparison. It's an illusion caused by the fact that values within a certain range are automatically cached in the process of autoboxing. It's the same problem we've always had with String values: comparing them with == sometimes "works" because you're actually comparing two references to the same, cached object.

When dealing with strings we can just tell the n00bs never to compare them with ==, as we've been doing all along. But comparing primitives with == is perfectly valid; the trick (thanks to autoboxing) is being sure the values really are primitives. The compiler will now let us declare a variable as an Integer and use it as if it were an int; that means we have to exercise a greater level of discipline and treat it as an error when someone does so without good reason.

Alan Moore