Hi all, I'm new to Java. While coding a Map<>, I found out that declaring Map<int, int>
is a syntax error while Map<Integer, Integer>
is OK. Is it only possible in Java to instantiate generics over object types, as opposed to primitives? If so, is there a noticeable performance penalty for boxing/unboxing of primitives?
views:
198answers:
4Yes, 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
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
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.
As others have noted there is a performance penalty for using wrapper classes for primitives. And even though the cost is not really noticeable, if you REALLY need the extra performance boost you can simply create custom subclasses for the List class, one for each primitive type (they are not many so that's not a problem) and simply override the methods that put and get values in the list and limit them to accepting each primitive. This will result in the performance boost and keep the verbosity of the generic list code.