When to Use Wrapper Class and Primitive Type

When to use wrapper class and primitive type

Others have mentioned that certain constructs such as Collections require objects and that objects have more overhead than their primitive counterparts (memory & boxing).

Another consideration is:

It can be handy to initialize Objects to null or send null parameters into a method/constructor to indicate state or function. This can't be done with primitives.

Many programmers initialize numbers to 0 (default) or -1 to signify this, but depending on the scenario, this may be incorrect or misleading.

This will also set the scene for a NullPointerException when something is being used incorrectly, which is much more programmer-friendly than some arbitrary bug down the line.

What is the real difference between primitives and wrapper classes in Java

The real difference is that primitive types are not reference types.

In Java type system, reference types have a common root, while primitive types do not: All reference types are subtypes of Object. In comparison, primitive types do not have a common root; each primitive type is its own special unicorn.

This means that a variable declared with Object type can hold a value of any reference type, but it cannot hold a value of any primitive type.

This is a problem if you want to create data structures that are generally useful. Consider how you would implement a "dynamic array" data structure like ArrayList or Vector. You could use an array Object[] to store the elements, and that would work for all reference types. But since primitive types don't have a common root you would have to create a separate implementation for each primitive type.

To solve this problem, wrapper classes were created. Now, instead of needing 8 separate implementations of dynamic array (1 for reference types and 7 for primitive types), you could wrap each primitive value in an object, and just use the implementation for reference types.

Primitive types and wrapper classes were created at the same time, when the first design and implementation of Java 1.0 were made. The designers did not "reuse what was already available" because nothing was available: they built everything from scratch.

Could the designers have solved the problem some other way, maybe by creating a type system that had a common root for both primitive and reference types? Yes, but they didn't, and they probably had good reasons: implementation complexity, ease of understanding, time to market, ...

Should I use a wrapper or primitive type as field while using Jackson

Wrapper class: java.lang.Integer

Pros:

  • Allows null value, therefore giving the chance to the user to leave a blank / non-specified field
  • Fast when values are between -128 and 127, as it uses its internal cache instead of creating new objects

  • Integer::valueOf for parsing String's

Cons:

  • Immutable: if you have to reset the value (e.g: because it exceeded a certain range), you'll have to re-create a whole new Integer instance.

  • Slower calculation performance

  • java.lang.Integer is a reference to an instance. Each calculation will recreate a whole new Object


Primitive type: int

Pros:

  • Mutable (as long as non-final, and a setter is provided): easily allows: this.age = age > MAX_AGE ? blabla : age;

  • primitive types calculations are faster

  • Integer::parseInt for parsing String's

Cons:

  • Non-selected values will be automatically set to 0; this may create confusion on whether the user selected 0 as value, or did not select anything

It seems the only advantage of java.lang.Integer is the blank / null value.

Also, in cases where a wrapper is needed, e.g:

List<Integer> myList;

you can directly add an unboxed value myList.add(2); which is interpreted by the compiler as myList.add(Integer.valueOf(2));

Best Practices : What to use, wrapper classes or primitive data types?

Use the primitive type unless you have no other choice. The fact that it's not nullable will prevent many bugs. And they're also faster.

Besides collections, wrapper types are typically used to represent a nullable value (for example, coming from a database nullable column).

primitives vs wrapper class initialization

The initialization in the 1st case is a simple assignment of a constant value. Nothing interesting... except that this is a primitive value that is being assigned, and primitive values don't have "identity"; i.e. all "copies" of the int value 20 are the same.

The 2nd and 3rd cases are a bit more interesting. The 2nd form is using "boxing", and is actually equivalent to this:

Integer i = Integer.valueOf(20);

The valueOf method may create a new object, or it may return a reference to an object that existed previously. (In fact, the JLS guarantees that valueOf will cache the Integer values for numbers in the range -128..+127 ...)

By contrast new Integer(20) always creates a new object.

This issue with new object (or not) is important if you are in the habit of comparing Integer wrapper objects (or similar) using ==. In one case == may be true if you compare two instances of "20". In the other case, it is guaranteed to be false.

The lesson: use .equals(...) to compare wrapper types not ==.


On the question of which to use:

  • If i is int, use the first form.
  • If i is Integer, the second form is best ... unless you need an object that is != to other instances. Boxing (or explicitly calling valueOf) reduces the amount of object allocation for small values, and is a worthwhile optimization.

Which is better? Primitive datatypes or Wrapper classes?

From Effective Java - Joshua Bloch

Item 49- Prefer primitive types to boxed primitives

Use primitives in preference to boxed primitives whenever you have choice. Primitive types are simple and faster. If you must use boxed primitives, be careful!
Autoboxing reduces the verbosity, but not the danger, of using boxed primitives


So if your need is not fulfilled by primitives then you use boxed primitives, Like in case of Collections

What is the main difference between primitive type and wrapper class?

None.

That's the exact same thing. In the first case you just have a supplementary variable.

Note that with autoboxing you rarely need to have both an int and an Integer variables. So for most cases this would be enough :

int pInt = 500;

The main case where the Integer would be useful is to distinguish the case where the variable is not known (ie null) :

Integer i = null; // possible
int i = null; // not possible because only Object variables can be null

But don't keep two variables, one is enough.

Are wrappers of a primitive type primitives types too?

No, wrappers for primitives aren't primitives. That's the point of them: They're used to wrap primitives when an object reference is required instead of a primitive (such as in a List).

In that tree graphic, "Boolean" and "Integer" aren't class/type names, they're just labels (like "Floating-point" is).

Object fits into that tree at the top of "Non-Primitive".

So for instance, the wrappers would be under non-primitive types:


Data Type
/ \
/ \
/ \
/ \
Primitive Types Non-Primitive Types (base class: Object)
/ / \
/ / \
Numeric Types Primitive Wrapper Types (etc.)
/ / | \
/ / | \
Integer Types Char Integer Boolean
/
/
char

(Obviously that's very incomplete.)

As I understand, Object is a memory region that can contain any type in Java; from primitives to classes created by the programmer.

No, it's not a memory region. It's a type.

So, Object may contain both primitive and non-primitive data types.

No, a variable, instance member, or parameter of type Object (or any of its subtypes) can only contain an object reference, not a primitive like int or char. That's why we have wrappers for primitives, so we can store them (via a wrapper) where an object reference is expected.


Also note that the diagram is misleading in another way: "Floating Point" shouldn't be under "Integral." In computer science, "integral types" are integers (in mathematics, it's more complex than that). Which is why the JLS splits NumericType into IntegralType and FloatingPointType (ref).

And char is an integral type in Java.


FWIW, my rough pass at that sketch would look something like this:

Sample Image

The final would hopefully be less squashed and ugly. :-) Note that I'm repeating "Types" everywhere to avoid the appearance of using class names, and I've used typeface (like your original did) to call out when I'm using keywords or class names.

Benefits of using wrapper classes over primitives in Java

Collections in the first place, for example,List<Integer>, you cannot use primitive int here.
Actually any generic class / interface that can work with different object types like

public interface Callable<V> {
V call() throws Exception;
}

Note that wrapping is best done using not new Integer(i) but Integer.valueOf(i) the latter will try to use cache. Unwrapping is done as Integer.intValue(). These wrapping / unwrapping of primitives are so typical operations that Java 5 introduced autoboxing / unboxing

List<Integer> list = new ArrayList<>();
list.add(1);
int i = list.get(0);

this code is automatically converted by Java compiler into

list.add(Integer.valueIf(1));
int i = list.get(0).intValue(); // this is where NullPointerException sometimes happens


Related Topics



Leave a reply



Submit