Type inference

Hi,

We all know, that:

List<Integer> li=new ArrayList<Integer>();

List<?> l=li;

l.add(1);

won't compile. The main reason for that is that at runtime we lose

all the type information, so compiler can't be sure, whether it can

safely add some object to a list. Because <?> stands for all the types,

it would be safe to:

l.add("Text");

In runtime however, it would throw the ClassCastException if someone

would retrieve the object from the list:

Integer i=l.get(0);//let's forget for a while that in that case l.get(0) returns an

// Object - not an Integer ...

So to prevent it, compiler doesn't allow it (for the same reason

List<Object> l=new ArrayList<Integer> is not allowed).

Another thing, which could be worked around by the compiler, is the

fact that we have:

List<E>{

add(E e);

}

, so if we use List<?>, how does the add method signature look like ?

add(? e) ?. Therefore all methods with the type parameter in the signature

are not allowed to be invoked on any reference variables with wildcards associated

with it (even when the method might have an empty body).

My question is:

Why is compiler not smart enough to deduce that:

List<Integer> li=new ArrayList<Integer>();

List<?> l=li;

l.add(1);

l stands for List<Integer> ? It could had a look at li and see that

it is List<Integer> thus treating l the same way ... Was it really so

difficult to implement it ? I understand, that it would had to log all

the uses of that kind, so every possible assignment to l would have

to be resolved to a proper parameterized type, eg:

List<Integer> li=new ArrayList<Integer>();

List<?> l=li;// ok

l.add(1);// would be ok;

l.add("text");// it would raise error

List<String> ls-new ArrayList<String>();

l=ls;// ok

l.add("text");// now it is ok

l.add(1);// and now this would raise error

Any comments on that ?

Cheers,

Adrian

[2720 byte] By [AdrianSosialuka] at [2007-11-27 4:54:18]
# 1

> The main reason for that is that at runtime we lose

> all the type information, so compiler can't be sure,

> whether it can safely add some object to a list.

No, the reason in this case is that the compiler doesn't know the element type is Integer so it won't autobox the int '1' into an Integer, and List<?> means List of Object, and an 'int' isn't an object, so List<?>.add(int) doesn't compile.

ejpa at 2007-7-12 10:08:55 > top of Java-index,Core,Core APIs...
# 2

>

> No, the reason in this case is that the compiler

> doesn't know the element type is Integer so it won't

> autobox the int '1' into an Integer, and List<?>

> means List of Object, and an 'int' isn't an object,

> so List<?>.add(int) doesn't compile.

No, this is not the reason. Adrian's initial explanation was closer to the truth.

First of all, List<?> does not mean "List of Object". It means "typesafe List of an unknown element type". This is a fundamental difference. And second of all, if it really were "List of Object", there would be no autoboxing problem at all. The compiler autoboxes the "1" into an Integer and then passes it to any method that expects an Object. Try it!

McNeppa at 2007-7-12 10:08:55 > top of Java-index,Core,Core APIs...
# 3

> Was it really so

> difficult to implement it ?

What makes you think that the development team tried to do this?

> I understand, that it

> would had to log all

> the uses of that kind, so every possible assignment

> to l would have

> to be resolved to a proper parameterized type, eg:

>

> List<Integer> li=new ArrayList<Integer>();

> List<?> l=li; // ok

> l.add(1);// would be ok;

> l.add("text");// it would raise error

> List<String> ls-new ArrayList<String>();

> l=ls; // ok

> l.add("text");// now it is ok

> l.add(1);// and now this would raise error

>

> Any comments on that ?

Let's assume for a moment that there is no technical barrier to doing this. What benefit would be gained that would warrant this effort? Is the only benefit that you would be able to reuse the same variable for different parameterized types?

dubwaia at 2007-7-12 10:08:55 > top of Java-index,Core,Core APIs...
# 4
> Hi,> > We all know, that:> [code]> List<Integer> li=new ArrayList<Integer>();> List<?> l=li;> l.add(1);....have you read this? http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
suparenoa at 2007-7-12 10:08:55 > top of Java-index,Core,Core APIs...
# 5

Hi,

Nothing makes me think that they even tried to do it.

But it would be helpful and very convenient and in my opinion

they know about it.

And it's not about reusebility but about being able to invoke

a method on a parameterized variable reference with wildcard

which has got a type parameter in its signature. As I explained earlier, it is

not possible to do it.

And yes, I have read sun's tutorial ... :)

Cheers,

Adrian

AdrianSosialuka at 2007-7-12 10:08:55 > top of Java-index,Core,Core APIs...
# 6

> And it's not about reusebility but about being able

> to invoke

> a method on a parameterized variable reference with

> wildcard

> which has got a type parameter in its signature. As I

> explained earlier, it is

> not possible to do it.

Maybe I don't understand what you are saying here but it doesn't seem to have much to do with the example of what you said you wanted before. Maybe you can clarify. There is no method signature in your example that I can see.

dubwaia at 2007-7-12 10:08:55 > top of Java-index,Core,Core APIs...
# 7
Hi Dubwai,Yes - you are absolutely right ... What you said in the previous postis very accurate to what I was proposing :)There is no use of that.Thanks for clarifying that.Adrian
AdrianSosialuka at 2007-7-12 10:08:55 > top of Java-index,Core,Core APIs...