tags:

views:

1260

answers:

6

I am trying to create

ArrayList<int> = new ArrayList<int>();

in Java but that does not work.

Can someone explain why int as type parameter does not work?
Using Integer class for int primitive works, but can someone explain why int is not accepted?

Java version 1.6

+1  A: 

You can't use primitives as type parameters in Java. Java's generics worth through type erasure, meaning that the compiler checks that you're using the types as you've defined them, but upon compilation, everything is treated as an Object. Since int and other primitives aren't Objects, they can't be used. Instead, use Integer.

Pesto
+20  A: 

Java generics are so different from C++ templates that I am not going to try to list the differences here. (See What are the differences between “generic” types in C++ and Java? for more details.)

In this particular case, the problem is that you cannot use primitives as generic type parameters (see JLS §4.5.1: "Type arguments may be either reference types or wildcards.").

However, due to autoboxing, you can do things like:

List<Integer> ints = new ArrayList<Integer>();
ints.add(3); // 3 is autoboxed into Integer.valueOf(3)

So that removes some of the pain. It definitely hurts runtime efficiency, though.

Michael Myers
+1, precisely what I was going to say!
coobird
Java generics are just an illusion
BlackTigerX
Java genewics are a dweam wiffin a dweam. The dweam of typesafe code wiffin the dweam of backward compatibility.
Michael Myers
Sorry, lack of sleep there.
Michael Myers
+3  A: 

that's because int is a primitive, it is a known issue.

If you really wanted to, you can subclass/write your own collection that can do that.

yx
+1 Thanks
yesraaj
+6  A: 

The reason that int does not work is that you cannot use primitive types as generic parameters in Java.

As to you're actual question, how is C++ templates different from Java generics, the answer is ... really really different. It's essentially two completely different approaches to implementing a similar end effect.

Java tends to focus on the definition of the generic. That is the validity of the generic definition is checked by only considering the code in the generic. If parameters are not properly constrained certain actions cannot be performed on them. The actual type it is eventually invoked with is not considered.

C++ is the opposite. Only minimal verification is done on the template itself. It really only needs to be parsable to be considered valid. The actual correctness of the definition is done at the place in which the template is used.

JaredPar
+1 for a gallant attempt to explain the difference :-) (although I might take issue with the minimal verification of C++ templates - any code not depending on the template parameters is fully checked)
James Hopkin
Also, just so people know, the C++ community has put much effort into addressing the concerns about minimal verification of dependent template code (especially when it leads to cryptic error messages). C++0x will have templates that can be constrained by 'Concepts' and their definition will be fully verified when the definition is first encountered (error messages will make much more sense). C++0x will also have unconstrained templates of course (which have their own advantages :).
Faisal Vali
@Faisal: To keep this up to date, I should probably mention that since your comment "concepts" have been removed from C++0x (now probably C++0B). This was, shall we say, not a universally popular decision.
David Thornley
+1  A: 

They are very different concepts, which can be used to perform some, but not all of the same tasks. As said in the other responses, it would take a quite a bit to go over all the differences, but here's what I see as the broad strokes.

Generics allow for runtime polymorphic containers through a single instantiation of a generic container. In Java, all the (non-primitive) objects are references, and all references are the same size (and have some of the same interface), and so can be handled by the bytecode. However, a necessary implication of having only instantiation of byte code is type eraser; you can't tell which class the container was instantiated with. This wouldn't work in c++ because of a fundamentally different object model, where objects aren't always references.

Templates allow for compile time polymorphic containers through multiple instantiations (as well as template metaprogramming by providing a (currently weakly typed) language over the c++ type system.). This allows for specializations for given types, the downside being potential "code bloat" from needing more than one compiled instantiation.

Templates are more powerful than generics; the former is effectively another language embedded within c++, while to the best of my knowledge, the latter is useful only in containers

Todd Gardner
A: 

You could try TIntArraList from GNU Trove which will act like an ArrayList of int values.

Peter Lawrey