views:

277

answers:

5

Hi,

Java collections only stores objects not primitive types but we can store using wrapper classes.Why this constrain?

Thx

+2  A: 

There is the concept of auto-boxing and auto-unboxing. If you attempt to store an int in a List<Integer> the Java compiler will automatically convert it to an Integer.

Jeremy
I think its added after java 1.5 ..right?
JavaUser
Autoboxing was introduced in Java 1.5 along with Generics.
Jeremy
+1  A: 

It was a Java design decision (mistake). Containers want Objects and primitives don't derive from Object.

Generics allow you to pretend there is no wrapper, but you still pay the performance price of boxing. This is IMPORTANT to many programmers.

A good explanation on SO already: http://stackoverflow.com/questions/1040384/why-do-some-languages-need-boxing-and-unboxing

And criticism of Java generics: http://stackoverflow.com/questions/520527/why-do-some-claim-that-javas-implementation-of-generics-is-bad

This is one place that .NET designers learned from the JVM mistake and implemented value types and generics such that boxing is eliminated in many cases.

Boxing is not a solution, nor is auto-boxing. They are implementation detail leaking into the language. Autoboxing is nice syntactic sugar, but is still a performance penalty, nonetheless.

mrjoltcola
+1 for value types.
Thilo
+1  A: 

Its not really a constraint is it?

Consider if you wanted to create a collection that stored primitive values. How would you write a collection that can store either int, or float or char? Most likely you will end up with multiple collections, so you will need an intlist and a charlist etc.

Taking advantage of the object oriented nature of Java when you write a collection class it can store any object so you need only one collection class. This idea, polymorphism, is very powerful and greatly simplifies the design of libraries.

Vincent Ramdhanie
"How would you write a collection that can store either int, or float or char?" - With properly implemented generics / templates like other languages that do not pay the penalty of pretending everything is an object.
mrjoltcola
+1  A: 

It's a combination of two facts:

  • Java primitive types are not reference types (e.g. an int is not an Object)
  • Java does generics using type-erasure of reference types (e.g. a List<?> is really a List<Object> at run-time)

Since both of these are true, generic Java collections can not store primitive types directly. For convenience, autoboxing is introduced to allow primitive types to be automatically boxed as reference types. Make no mistake about it, though, the collections are still storing object references regardless.

Could this have been avoided? Perhaps.

  • If an int is an Object, then there's no need for box types at all.
  • If generics aren't done using type-erasure, then primitives could've been used for type parameters.
polygenelubricants
+1  A: 

Makes the implementation easier. Since Java primitives are not considered Objects, you would need to create a separate collection class for each of these primitives (no template code to share).

You can do that, of course, just see GNU Trove or Apache Commons Primitives.

Unless you have really large collections, the overhead for the wrappers does not matter enough for people to care (and when you do have really large primitive collections, you might want to spend the effort to look at using/building a specialized data structure for them).

Thilo