Why not auto-box Java primitive types for Generics?
Asked Answered
D

6

8

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?

Dulsea answered 12/8, 2011 at 6:49 Comment(5)
Take a look at the List interface. What would do lst.remove(5) if autoboxing were allowed in Generics?Uralian
The same thing that will happen if I had an ArrayList<Integer> lst; and then called lst.remove(5);Dulsea
@shrini1000: Serabe's point is that there's an overloading ambiguity there, if the type parameter was int, it would conflict with the other method that takes an int; whereas this ambiguity does not arise if the type parameter was IntegerBezanson
@newacct: there's really no ambiguity here. remove(int n) will try to remove n'th element, remove(new Integer(5)) would try to remove a matching object element. My point is: if there's no such ambiguity for ArrayList<Integer>, and if we can somehow promote ArrayList<int> to ArrayList<Integer>, then we should be fine.Dulsea
No, we wouldn't be fine. If you add autoboxing, for consistence's shake, you should add it to every method. If I make ArrayList<int> I want to (and expect to be able to) add an int, after all, that's what I declared.Uralian
B
7

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?)

Bezanson answered 12/8, 2011 at 9:4 Comment(1)
Your point about arrays is a key one. An int encapsulates a value, and an Integer, by identifying a thing which will always encapsulates some particular value, effectively encapsulates that value. By contrast, an int[] identifies an entity, and an Integer[] *identifies a different kind of entity*. If a function is supposed to return an T[]` which is supposed to change in some fashion under some particular condition, there's no way it can return an int[] which changes properly under that condition without being specifically coded for that type.Rayraya
D
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.

Dianemarie answered 12/8, 2011 at 7:11 Comment(0)
A
1

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.

Appertain answered 12/8, 2011 at 7:24 Comment(2)
But same is true for ArrayList<Integer>, and yet that is allowed. So why not just automatically promote ArrayList<int> to ArrayList<Integer>?Dulsea
@Shrini, Integer is an object and not a primitive. We don't want to automatically wrap a primitive Generics to an Object Generics, which will add another layer of wrapping on top of the Generics and add the performance costs of autoboxing of top of it. I don't like that idea.Appertain
B
0

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>

Byram answered 12/8, 2011 at 6:59 Comment(0)
B
0

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.

Bangor answered 12/8, 2011 at 7:8 Comment(0)
O
-1

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.

Oppugnant answered 12/8, 2011 at 6:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.