Downcasting a subclass of a concrete generic

Hi--

Been puzzling over this one for quite awhile, and I still can't figure it out. I'm trying to downcast a generic type to a subclass of a concrete type. Now admittedly that's messy and I'd like to refactor, but I'm still puzzled. Take the following code:

publicclass Test1<T>{

protectedfinal T obj;

public Test1(T obj){

this.obj = obj;

}

publicstaticvoid main(String[] args){

Test1<?> testObj =new Test2("hello");

System.err.println("Calling a method: " + ((Test2) testObj)).aMethod());

}

}

publicclass Test2extends Test1<String>{

public Test2(String obj){

super(obj);

}

public String aMethod(){

return obj;

}

}

This fails to compile, saying that Test1<capture of ?> isn't convertible to Test2.

Now suppose I change to the following:

publicclass Test1<T>{

protectedfinal T obj;

public Test1(T obj){

this.obj = obj;

}

publicstaticvoid main(String[] args){

Test1<?> testObj =new Test2<String>("hello");

System.err.println("Calling a method: " + ((Test2) testObj).anotherMethod());

}

}

publicclass Test2<Textends String>extends Test1<T>{

public Test2(T obj){

super(obj);

}

public String anotherMethod(){

return obj;

}

}

Here all I've done is add a parameter to the Test2 type that gives the same information available in item 1. In this case, however, it compiles and runs fine.

Even more oddly, the following also works and does not produce any warnings:

publicclass Test1<T>{

protectedfinal T obj;

public Test1(T obj){

this.obj = obj;

}

publicstaticvoid main(String[] args){

Test1<?> testObj =new Test2("hello");

System.err.println("Calling a method: " + ((Test2) ((Test1) testObj)).anotherMethod());

}

}

publicclass Test2extends Test1<String>{

public Test2(String obj){

super(obj);

}

public String anotherMethod(){

return obj;

}

}

So essentially the system is ok as long as I cast the generic type to a raw type, and then downcast to the subclass of the concrete type... but I can't do the cast directly?

My feeling is that Java is being a little overly touchy about trying to prevent casting to a concrete type-- in the case where the type you're trying to cast to is itself not generic, shouldn't that be allowed? Or am I missing something subtle about how the generics work?

[5379 byte] By [Liam3851a] at [2007-11-27 9:50:53]
# 1

Correct me if I'm wrong, but I think this may be your problem:

public class Test2 extends Test1<String> {

...

}

This means that Test2 is a subclass of Test1<String> -- not Test1<?>. Here's why.

If we "expand out," say, Test1<Integer> and Test1<String>, we get the following:

public class Test1String {

protected final String obj;

public Test1String(String obj) {

this.obj = obj;

}

...

}

public class Test1Integer{

protected final Integer obj;

public Test1Integer(Integer obj) {

this.obj = obj;

}

...

}

Now, it's easy to see that inheriting from each of these classes yields completely different results. Once you've parameterized a class, it becomes a completely different beast. Sooo, saying that

Test1<?> testObj = new Test2("hello");

could be the same thing as saying (since ? means any parameter), in our expanded form,

Test1Integer testObj = new Test2("hello"); //aka, a new Test1String

//or Test1Object, Test1MyComplicatedType, whatever

which is clearly not allowed, since all the fields would be of a completely different type.

I hope this helps!

mr.hwortha at 2007-7-13 0:19:53 > top of Java-index,Core,Core APIs...
# 2

> Correct me if I'm wrong, but I think this may be

> your problem:

You are wrong.

@OP: I guess, you are using an older version of java compiler. There is a bug related with what you experience. Your code compiles fine in Java6, and I guess in current Java5, too. This is the bug entry:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4856982

stefan.schulza at 2007-7-13 0:19:53 > top of Java-index,Core,Core APIs...
# 3
*shakes head* I'm sorry, I shouldn't have posted on no sleep--I have no idea what I was doing there.Apologies.
mr.hwortha at 2007-7-13 0:19:53 > top of Java-index,Core,Core APIs...
# 4
> *shakes head* I'm sorry, I shouldn't have posted on> no sleep--I have no idea what I was doing there.You were thinking to complex ;)> Apologies.Sure.
stefan.schulza at 2007-7-13 0:19:53 > top of Java-index,Core,Core APIs...
# 5
Hi Stefan-- Thanks for pointing me to the bug report! I'd been searching but unable to find it. You're right, we were using 5.0u6 here. I tried using 5.0u12 and the problem described not occur. Thanks again,David
Liam3851a at 2007-7-13 0:19:53 > top of Java-index,Core,Core APIs...