Hello,
I've been learning and experimenting with Java Generics for a while but I have run into something that I cannot explain. Take for example the following code:
public class Question {
public <T> Sub<T> getSub(Class<T> c) {
return new Sub<T>(c);
}
public class Sub<S> {
private Class<S> c;
public Sub(Class<S> c) {
this.c = c;
}
public void add(S s) {
}
}
}
And the test code:
import generics.Question.Sub;
public class Answer {
public static void main(String [] args) {
Question q = new Question();
Sub<String> s = q.getSub(String.class);
s.add("");
}
}
When this is run it gives a wonderfully cryptic error message:
C:\Answer.java:8: incompatible types
found : generics.Question.Sub<java.lang.String>
required: generics.Question.Sub<java.lang.String>
Sub<String> s = q.getSub(String.class);
1 error
Now, through some experimentation I have worked out how to prevent the compiler error. I can either make the Sub class a static inner class, or I need to refer to the Sub class as Question.Sub<String>. What I can't do is explain why I need to do this.
I've done some reading of the Java documentation on Generics but none cover this particular case.
Can anyone explain why the code is an incompatible type in its current form?
-Edit-
Looking at this closer I can see that I get the same behaviour outside of Netbeans. If I have the code in the following structure:
generics\
generics\Question.java
generics\Answer.java
When I compile the files together, I do not get the error:
C:\>javac generics\Question.java generics\Answer.java
C:\>
However, when I compile Question first and then Answer, I get the error:
C:\>javac generics\Question.java
C:\>javac generics\Answer.java
generics\Answer.java:8: incompatible types
found : generics.Question.Sub<java.lang.String>
required: generics.Question.Sub<java.lang.String>
Sub<String> s = q.getSub(String.class);
^
1 error
I have heard something mentioned about Type Erasure. Is this the case in this situation?