问题
Java does not allow primitive types to be used in generic data structures. E.g. ArrayList<int> is not allowed. The reason is, primitive types can not be directly converted to Object. However Java 1.5 does support auto-boxing, and wrapper classes work in generic data structures. So why couldn't the compiler auto-box it to ArrayList<Integer>? Are there any other reasons for why this can not work?
回答1:
So as far as I understand it, your proposed ArrayList<int>
would be identical to ArrayList<Integer>
. Is that right? (In other words, internally it still stores an Integer; and every time you put something in or get it out, it would automatically box/unbox it, but autoboxing/autounboxing already does that for ArrayList<Integer>
.)
If it is the same, then I don't understand what the utility of having a duplicate syntax <int>
is when it means the same thing as <Integer>
. (In fact it will introduce additional problems, because for example int[]
is not the same runtime type as Integer[]
, so if you have T[]
, and T
is int
, what would it mean?)
回答2:
The generic type information is erased at run time. Check this link. Generics have more to do with compile time checking than run time checking. The autoboxing and unboxing are the run time operations. See the link. This is the reason that autoboxing should not work with Generics.
回答3:
The problem will be in performance. For every get()
/set()
method, in the list, the JVM will have to unbox/box the respective value for the mentioned method respectively. Remember, autoboxing take primitive types and wraps them into an Object
and vice-versa, as stated on Autoboxing:
Finally, there are performance costs associated with boxing and unboxing, even if it is done automatically.
I think they wanted a List to do simple operation and alleviating performance all together.
回答4:
I don't think there's any technical reason it couldn't be done like you say, but there are always interface considerations: e.g., if you automatically converted objects of type ArrayList<int>
to be ArrayList<Integer>
, you lose some explicitness in terms of the interface specifications: it is less obvious that ArrayList in fact store objects, not primitives.
My understanding is that autoboxing is more for compatibility and flexibility in parameter types than for the ease of being able to say "int" instead of "Integer." Java's not exactly known for it's obsession with conciseness...
A small P.S.: I don't think it would technically be correct to say "autobox ArrayLint<int>
to ArrayList<Integer>
," because you aren't actually wrapping anything in an object "box" -- you're just actually converting a typename ArrayList<int>
to "actual" type ArrayList<Integer>
回答5:
I'm glad it is impossible, because int use much less memory than Integer and is much faster too. Therefore it forces me to think whether it is acceptable to use Collection<Integer>
or not (lot of times in business application it's ok, but in other apps it is not).
I would be much happier if Collection<int>
was possible and efficient, but it is not.
回答6:
I don't think this is any sort of problem - do you have any concrete case where is this limiting you somehow? And btw there is difference between int and Integer while the object can be null and primitive type can't.
来源:https://stackoverflow.com/questions/7036552/why-not-auto-box-java-primitive-types-for-generics