Saturday, January 9. 2016
Strange Issue with Generics
This entry is different because is a question for all of you. I am not sure about it and maybe you can help me to understand this weird issue. During the Christmas vacation I spent some of my spare time implementing my SPMLv2 library based in Java and JAXB (remember my series about that subject) and, because of the complicated inheritance of requests and responses in SPMLv2, I faced a strange behavior with generics.
The root of the problem is exemplified in the following class:
public class Wrap<T> {
T wrapped = null;
public Wrap() {
wrapped = null;
}
public Wrap(T wrapped) {
this.wrapped = wrapped;
}
public T get() {
return wrapped;
}
public <O> O another(O other) {
return other;
}
public static void main(String[] args) throws Exception {
new Wrap<Integer>().another(new String()).length();
new Wrap().another(new String()).length();
}
}
The Wrap class is generic based on a class T (no requirements, just any object) but it has the another method that depends on another different class O (any object again). The problem is that if you instantiate the class defining the generic T (the first line in the main method, new Wrap<Integer>()) it works as I think it is normal, the another generic method returns a String cos the argument passed is a String. Nevertheless if the generic class is instantiated generically (new Wrap() in the second line) the another method returns an Object instead of a String. I can understand that this should happen in the get method, because this method depends on T which is not defined, but not in another, cos O is another generic (not T) which is perfectly defined (it is clearly a String).
The resulting error in compilation is the following (any Java 7 or 8):
Wrap.java:23: error: cannot find symbol new Wrap().another(new String()).length(); ^ symbol: method length() location: class Object Note: Wrap.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
I do not understand this issue. Is it normal? Does anybody know why the second generic is not correctly derived? Is this behavior explained somewhere?
Thanks in advance!
Comments