Want to read Slashdot from your mobile device? Point it at m.slashdot.org and keep reading!

 



Forgot your password?
typodupeerror
×
User Journal

Journal severoon's Journal: POST: Re: an annoying quirk

This post was in response to a question concerning the introduction of generics in the Java 1.5 'Tiger' release. Someone wanted to know why an ArrayList reference with parameterized type Number couldn't refer to an ArrayList that was instantiated with parameterized type Integer. After all, it seems like a perfectly valid thing to do--a list of integers is indeed a list of numbers, is it not?

(By the way, the first line of my post refers to the fact that the post to which I'm responding had tried to type in an angle brackets directly instead of using the escape codes--< and >--so they were stripped out by /. as an unknown tag.)

_______________________

I'm guessing that you dropped some text between angle brackets, and what you meant to say was something along the lines of:

ArrayList<Integer> s = new ArrayList<Integer>();
ArrayList<Number> t = s; // does not compile

It is indeed true that, though s contains only Integers, which are all indeed Numbers as well, you cannot make this assignment. The reason is that, though Integer extends Number, the new types you've created (ArrayList<Integer> and ArrayList<Number>) using the genericized code have no such inheritance relationship with each other that would allow such an assignment.

In generics, when you instantiate a genericized class and specify a type parameter, you're effectively creating a new type. In the example of the ArrayList, an ArrayList<Integer> extends whatever object that ArrayList does, and implements all of its interfaces, but it does not extend ArrayList itself or any type-parameterized variant of ArrayList.

sev

_______________________

To this, I received a reply explaining a slightly different take, which I had considered already (I have taken the liberty of correcting a few misspellings and mistypes in the original):

The reason this can't be allowed is very simply: Look at this:

ArrayList<Integer> s = new ArrayList<Integer>();
ArrayList<Number> t = s; // Does not compile, but assume it would.
t.addElement(new Float(10.5)); // t should ONLY contain integers. Not good.
Integer i= s.elementAt(0); // Class cast exception.

Allowing t=s would ruin the entire "You are sure your collection only can contain what it say it contains, and we check that at compile time"

I replied:

_______________________

Subject: Example Given Is Neither Necessary Nor Sufficient

I too thought of this as a possible means of explaining this situation, but rejected it . The explanation you put forth here does not satisfy because the same argument could be applied to Integer[]s and Number[]s.

Alas, the corresponding array code does indeed compile, and it is well-defined and unambiguous:

Integer[] i = new Integer[3];
Number[] n = i;
n[0] = new Float(1.1);

There's no reason in generics why the compiler couldn't have been designed to similarly accept code if you replace the above arrays with type-parameterized ArrayLists. The same arguments that apply to this array code (in terms of allowing it to compile but rejecting it at runtime) are every bit as valid for parameterized types. Obviously, a different direction is required for generics to work, though, if the whole point is to provide the same capability but fail at compile-time.

sev

_______________________

This discussion has been archived. No new comments can be posted.

POST: Re: an annoying quirk

Comments Filter:

What good is a ticket to the good life, if you can't find the entrance?

Working...