views:

400

answers:

6

On the very high level, I know that we need to "wrap" the priminitve 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.

+15  A: 

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.

Justin Niessner
+1  A: 

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.

Boris Pavlović
Huh? Java has no pointers.
BalusC
You wrote: "These values then can be mutated". This is actually not true for the primitive object wrappers in Java. They are all immutable.
Asaph
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.
Helper Method
+1  A: 

See http://stackoverflow.com/questions/1949122/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.

ewernli
+1  A: 

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://joda-primitives.sourceforge.net/index.html)

nanda
Collections differentiate very well: They work pretty good with objects and slap you with compile errors if you try with java primitives!
Andreas_D
+1  A: 

To store the primitive type values in collection classes we require Wrapper classe.

Stardust
+2  A: 

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.

Kohsuke Kawaguchi
Can you elaborate on how primitive types and reference types are stored in the memory by JVM?
Midnight Blue
@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
@Justin N. - Thanks for the link
Midnight Blue
Primitive 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