Hello I have a method that should return different results depending on the type.
I can do like this to check the generic type.
public <T> T search(final String query){
T returnValue = null;
if (returnValue instanceof String){ }
if (returnValue instanceof Integer){ }
if (returnValue instanceof MyObject){ }
But why can't I do like this?
public <T> T search(final String query){
T returnValue = null;
if (T instanceof String){ }
if (T instanceof Integer){ }
if (T instanceof MyObject){ }
Calling code.
String id = myObjcet.<String> search("select ...");
Java implements generics "by erasure". That means that at runtime there is (nearly) no knowledge of generics at all. Instead, the compiler checks for generics, but under the cover it converts everything to Object (or to the nearest generics boundary).
If you decompile that method using javap, you'll see that it reads :
public Object search(...
Every reference to T is removed.
This is a serious limitation of generics in Java, which is reflected often also in the JRE classes with constructs like :
SomeClass<String> x = new SomeClass<String>(String.class);
Where the third repetition of String (String.class) is needed because the constructor needs to know which class it is operating on.
This paradigm, despite being horrible, could solve your problem.
Informations about generics are actually contained in the .class files, as metadata, they can be inspected using reflection and up to some extent also resolved. However, this is not possible in a case like yours, but it is for example used by ORMs on list getters. for example, using Hibernate, a getter like this :
public List<Group> getGroups() {
Can be inspected by Hibernate so that it knows that the list is supposed to hold instances of Group, adapting its queries accordingly.
(However, even if generics where not implemented this way, T is not an instance, it is a class, writing String instanceof String is equally wrong. It should be if (T.equals(String.class)) )
Because T
is erased at runtime. It's only there at compile time. returnValue
is the variable -- it is present at runtime.
public <T> T search(Class<T> clazz, String query){
T returnValue = null;
if (clazz==String.class){ }
if (clazz==Integer.class){ }
if (MyObject.clazz.isAssignableFrom(clazz){ }
String id = myObjcet.search(String.class, "select ...");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With