Java Generics - <int> to <Integer>
In the way of learning Java Generics, I got stuck at a point.
It was written "Java Generics works only with Objects and not the primitive types".e.g
Gen<Integer> gen=new Gen<Integer>(88); // Works Fine ..
But, with the primitive types like int,char etc ...
Gen<int> gen=new Gen<int>(88) ; // Why this results in compile time error
I mean to say, since java generics does have the auto-boxing & unboxing feature, then why this feature cannot be applied when we declare a specific type for our class ?
I mean, why
Gen<int>
doesn't automatically get converted toGen<Integer>
?
Please help me clearing this doub开发者_C百科t.
Thanks.Autoboxing doesn't say that you can use int instead of Integer. Autoboxing automates the process of boxing and unboxing. E.g. If I need to store some primitive int to a collection, I don't need to create the wrpper object manually. Its been taken care by Java compiler. In the above example you are instantiating an generic object which is of Integer type. This generic object will still work fine with int but declaring int as a generic type is wrong. Generics allow only object references not the primitives.
As you have discovered, you can't mention a primitive type as a type parameter in Java generics. Why is this the case? It is discussed at length in many places, including Java bug 4487555.
The simple explanation: Generics are defined that way.
A good reason from the Java perspective: It simplifies type erasure and translation to byte code for the compiler. All the compiler needs to do is some casting.
With non-primitives the compiler would have to decide whether to cast or to inbox/outbox, it would to need to have additional validating rules (extends
and &
wouldn't make sense with primitives, should a ?
include primitives, yes or no? and so on) and have to handle type conversions (assume you parametize a collection with long
and add an int
...?)
A good reason from a programmers perspective: operations with a bad performance are kept visible! Allowing primitves as Type Arguments would require hidden autoboxing (inboxing for store, outboxing for read operations. Inboxing may create new objects which is expensive. People would expect fast operations if they parametize a generic class with primitives but the opposite would be true.
That's a very good question.
As you suspected, the abstraction could surely be extended to the type parameters, and made them trasparent to the programmer. In fact, that is what most modern JVM languages do (statically typed ones, of course). Examples include Scala, Ceylon, Kotlin etc.
This is what your example would look like in Scala:
val gen: Gen[Int] = new Gen[Int](80)
Int
is just a regular class, just like other classes. There is no primitive-object distinction whatsoever.
As to why Java people did not do it... I don't actually know the reason, but I imagine such an abstraction would not fit with the existing Java specification without overcomplicating the semantics (or without sacrificing the backward compatibility, which is certainly not a viable option).
精彩评论