Java noob: generics over objects only?
Solution 1:
Yes, you can only use reference types for generic type parameters, and yes, there will be some performance penalty due to boxing/unboxing (which can be done automatically for the most part).
Here's a quote from the Java Generics FAQs:
Are primitive types permitted as type arguments?
No. Only reference types can be used as type arguments. A parameterized type such as
List<int>
orSet<short>
is illegal. Only reference types can be used for instantiation of generic types and methods. Instead ofList<int>
we must declare aList<Integer>
, using the corresponding wrapper type as the type argument.[...] Note, that the lack of primitive type instantiations incurs a performance penalty. Autoboxing and -unboxing make the use of wrapper type instantiations of generic types very convenient and concise in the source code. But the concise notation hides the fact that behind the curtain the virtual machine creates and uses lots of wrapper objects, each of which must be allocated and later garbage collected. The higher performance of direct use of primitive type values cannot be achieved with generic types. Only a regular type can provide the optimal performance of using primitive type values.
If you absolutely need the performance, Trove has many data structures specialized for primitive types, but for most practical purposes, using boxed primitive types with Java Collections Framework classes should yield more than acceptable performance.
See also
- Effective Java 2nd Edition, Item 49: Prefer primitive types to boxed types
- Java Language Guide/Autoboxing
- Java Language Guide/Generics
- Java Tutorials/Generics
Solution 2:
Is it only possible in Java to instantiate generics over object types, as opposed to primitives?
correct.
If so, is there a noticeable performance penalty for boxing/unboxing of primitives?
yes, there is.
See here for a detailed description: http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html
Solution 3:
1) Yes, Java generics only work on object types. This is because of how they're implemented, which is through type erasure - essentially, once it's compiled down to bytecode all generic types are replaced with Object
- this was done so that java generics could work without modifying the underlying JVM/bytecode (bad decision, imo).
2) Yes, there will some boxing / unboxing penalty; can't be avoided, I'm afraid.