On the very high level, I know that we need to "wrap" the primitive data types, such as int and char, by using their respective wrapper classes to use them within Java collections.I would like to understand how Java collections work at the low level by asking:"why do we need to wrap primitive data types as objects to be able to use them in collections?"I thank you in advance for your help.
-
possible duplicate of [Why are there wrapper classes in Java?](http://stackoverflow.com/questions/3579035/why-are-there-wrapper-classes-in-java) – nbro Jan 01 '15 at 20:25
12 Answers
Because Java collections can only store Object References (so you need to box primitives to store them in collections).
Read this short article on Autoboxing for more info.
If you want the nitty gritty details, it pretty much boils down to the following:
Local Primitives are stored on the Stack. Collections store their values via a reference to an Object's memory location in the Heap. To get that reference for a local primitive, you have to box (take the value on the Stack and wrap it for storage on the Heap) the value.

- 242,243
- 40
- 408
- 536
At the virtual machine level, it's because primitive types are represented very differently in memory compared to reference types like java.lang.Object and its derived types. Primitive int in Java for example is just 4 bytes in memory, whereas an Object takes up at minimum 8 bytes by itself, plus another 4 bytes for referencing it. Such design is a simple reflection of the fact that CPUs can treat primitive types much more efficiently.
So one answer to your question "why wrapper types are needed" is because of performance improvement that it enables.
But for programmers, such distinction adds some undesirable cognitive overhead (e.g., can't use int and float in collections.) In fact, it's quite possible to do a language design by hiding that distinction --- many scripting languages do this, and CLR does that. Starting 1.5, Java does that, too. This is achieved by letting the compiler silently insert necessary conversion between primitive representation and Object representation (which is commonly referred to as boxing/unboxing.)
So another answer to your question is, "no, we don't need it", because the compiler does that automatically for you, and to certain extent you can forget what's going on behind the scene.

- 3,567
- 3
- 19
- 21
-
1Can you elaborate on how primitive types and reference types are stored in the memory by JVM? – Midnight Blue Jan 25 '10 at 19:18
-
2@Midnight Blue - Read the first answer (by Jon Skeet) here: http://stackoverflow.com/questions/2099695/java-array-is-stored-in-stack-or-heap. It explains more about how things are stored in the JVM and when. – Justin Niessner Jan 25 '10 at 19:23
-
-
1Primitive types are represented as simple values in memory, almost always just like how they are represented in C. For example, Java int is 32-bit integer, so it takes up 4 bytes. The actual representation in memory is CPU specific --- see big endian vs little endian. Representation of the reference types is JVM specific, but for example on 32bit HotSpot, IIRC the first 4 bytes refers to the 'klass' data structure (which represents the type of the object), next 4 bytes refer to the method dispatch table, and instance fields follow. – Kohsuke Kawaguchi Jan 25 '10 at 19:28
Read all of the answers, but none of them really explains it simply in layman terms.
A wrapper class wraps(encloses) around a data type (can be any primitive data type such as int, char, byte, long) and makes it an object.
Here are a few reasons why wrapper classes are needed:
Allows
null
values.Can be used in collection such as
List
,Map
, etc.Can be used in methods which accepts arguments of
Object
type.Can be created like Objects using
new ClassName()
like other objects:Integer wrapperInt = new Integer("10");
Makes available all the functions that
Object
class has such asclone()
,equals()
,hashCode()
,toString()
etc.
Wrapper classes can be created in two ways:
Using constructor:
Integer i = new Integer("1"); //new object is created
Using
valueOf()
static method:Integer i = Integer.valueOf("100"); //100 is stored in variable
It is advised to use the second way of creating wrapper classes as it takes less memory as a new object is not created.

- 3,642
- 3
- 25
- 42

- 17,953
- 10
- 93
- 108
To store the Primitive type values in Collection. We require Wrapper classes.

- 3,642
- 3
- 25
- 42

- 1,115
- 6
- 22
- 33
Primitive data types can't be referenced as memory addresses. That's why we need wrappers which serve as placeholders for primitive values. These values then can be mutated and accessed, reorganized, sorted or randomized.

- 63,078
- 28
- 122
- 148
-
1You wrote: "These values then can be mutated". This is actually not true for the primitive object wrappers in Java. They are all immutable. – Asaph Jan 25 '10 at 19:13
-
A reference basically is a pointer, just a little more restrictive. In my opinion they should have called it pointer instead of reference, as the term "reference" is very misleading. – helpermethod Jan 25 '10 at 19:23
-
Moreover, we call it a reference variable. But, actually it is a reference to the variable(object) and ironically, we don't have variable(object) mentioned there. So it is a reference to the unnamed variable(object) :) – Chaitanya Sep 27 '13 at 08:57
-
@helpermethod: I'd have preferred "object identifier", but "heap object reference" also works. I don't like the term "pointer" because references don't work like standard pointers. If a normal pointer is never accessed, its content will have no effect on any code execution. In languages with pointers, it's perfectly legitimate for code to hold pointers to things that no longer exist, provided that no attempt is made to access them. By contrast, the existence of heap object references may observably impact system behavior whether or not code ever accesses them, and... – supercat Feb 07 '14 at 20:56
-
...the existence of a single non-null reference anywhere which is reachable but does not identify a valid object would be cause for an instant system meltdown in both Java and .NET. – supercat Feb 07 '14 at 20:58
Collection uses Generics as the bases. The Collection Framework is designed to collect, store and manipulate the data of any class. So it uses generic type. By using Generics it is capable of storing the data of ANY CLASS whose name you specify in its declaration.
Now we have various scenario in which want to store the primitive data in the same manner in which the collection works. We have no way to store primitive data using Collection classes like ArrayList, HashSet etc because Collection classes can store objects only. So for storing primitive types in Collection we are provided with wrapper classes.
Edit: Another benefit of having wrapper classes is that absence of an object can be treated as "no data". In case of primitive, you will always have a value.
Say we have method signature as
public void foo(String aString, int aNumber)
you can't make aNumber
as optional in above method signature.
But if you make signature like:
public void foo(String aString, Integer aNumber)
you have now made aNumber
as optional since user can pass null
as a value.

- 904
- 6
- 19
See Boxing and unboxing: when does it come up?
It's for C#, but the same concept apply to Java. And John Skeet wrote the answer.
Well, the reason is because Java collections doesn't differentiate between primitive and Object. It processes them all as Object and therefore, it will need a wrapper. You can easily build your own collection class that doesn't need wrapper, but at the end, you will have to build one for each type char, int, float, double, etc multiply by the types of the collections (Set, Map, List, + their implementation).
Can you imagine how boring that is?
And the fact is, the performance it brings by using no wrapper is almost negligible for most applications. Yet if you need very high performance, some libraries for primitive collections are also available (e.g. http://www.joda.org/joda-primitives/)

- 60,927
- 15
- 95
- 117

- 24,458
- 13
- 71
- 90
-
Collections differentiate very well: They work pretty good with objects and slap you with compile errors if you try with java primitives! – Andreas Dolk Jan 25 '10 at 19:24
Wrapper classes provide useful methods related to corresponding data types which you can make use of in certain cases.
One simple example. Consider this,
Integer x=new Integer(10);
//to get the byte value of 10
x.byteValue();
//but you can't do this,
int x=10;
x.byteValue(); //Wrong!
can you get the point?

- 4,890
- 4
- 24
- 31
If a variable is known to either hold a specific bit pattern representing null
or else information which can be used to locate a Java Virtual Machine object header, and if the method for reading an object header given a reference will inherently trap if given the bit pattern associated with null
, then the JVM can access the object identified by the variable on the assumption that there is one. If a variable could hold something which wasn't a valid reference but wasn't the specific null
bit pattern, any code which tried to use that variable would have to first check whether it identified an object. That would greatly slow down the JVM.
If Object
derived from Anything
, and class objects derived from Object
, but primitives inherited from a different class derived from Anything
, then in a 64-bit implementation it might be practical to say that about 3/4 of the possible bit patterns would represent double
values below 2^512, 1/8 of them to represent long
values in the range +/- 1,152,921,504,606,846,975, a few billion to represent any possible value of any other primitve, and the 1/256 to identify objects. Many kinds of operations on things of type Anything
would be slower than with type Object
, but such operations would not be terribly frequent; most code would end up casting Anything
to some more specific type before trying to work with it; the actual type stored in the Anything
would need to be checked before the cast, but not after the cast was performed. Absent a distinction between a variable holding a reference to a heap type, however, versus one holding "anything", there would be no way to avoid having the overhead extend considerably further than it otherwise would or should.

- 77,689
- 9
- 166
- 211
Much like the String class, Wrappers provide added functionality and enable the programmer to do a bit more with the process of data storage. So in the same way people use the String class like....
String uglyString = "fUbAr";
String myStr = uglyString.toLower();
so too, they can with the Wrapper. Similar idea.
This is in addition to the typing issue of collections/generics mentioned above by Bharat.

- 1
- 3
because int does not belongs any class . we convert datatype(int) to object(Interger)

- 892
- 9
- 9