The following code does not compile:
public class GenericsTest { public static void main(String[] args) { MyList<?> list = new MyList<Object>(); Class<?> clazz = list.get(0); // Does not compile with reason // 'Type mismatch: cannot convert from Object to Class' MyList list2 = new MyList(); Class clazz2 = list2.get(0); } static class MyList<T> extends ArrayList<Class<T>> { } }
I wanted to do this to introduce generics to old code without breaking the build.
Is this a bug in both the compiler (both eclipse and javac) or am I missing something here? What other possibility exists to introduce generics to MyList?
EDIT
For clarification:
I have the generic class
public class MyList extends ArrayList<MyObject> {}
with
public class MyObject {}
and code using MyList
MyList list = new MyList(); ... MyObject o = list.get(0);
Now during development I see I want to introduce generics to MyObject
public class MyObject<T> {}
and now I want to have this new generic thingy in MyList as well
public class MyList<T> extends ArrayList<MyObject<T>> {}
But that does break my build. Interestingly
public class MyList<T> extends ArrayList<MyObject<T>> { public MyObject<T> get(int i) { return super.get(i); } }
will allow old code
MyList list = new MyList(); ... MyObject o = list.get(0);
to compile.
OK, seems that when I introduce this generic, I will have to live with having to change all calls to MyList to the generic form. I wanted the old code to just introduce a warning instead of an error.
I think you are not understanding quite how generics work.
This code snippet does not compile because you are telling the compiler that
listis going to holdClass<Object>types – and then in the next line you are expecting it to return you aClass<String>. The generic system in Java is not capable of converting types used with generics based on inheritance like you might think it would.If you expect
listto holdClass<String>, then you need to declare it as so – or, if you want it to be able to hold any types, then you cannot do the second line without a cast.or
The second code snippet does not work because when you use raw types, you still need to cast the
Objectreturned byget()to the declared type you are using (which has always been the case).