I wanted to create a GenericBuilder that could be used to retrieve the Builder classes that are defined inside my classes. I created the following interfaces and classes
public interface BuilderType<T> {
}
public class MyObject implements BuilderType<MyObject.MyObjectBuilder> {
private int i;
private MyObject() {}
public int getI() {
return i;
}
public static MyObjectBuilder buildMyObject() {
MyObjectBuilder builder = new MyObjectBuilder();
return builder;
}
public static class MyObjectBuilder {
private final MyObject obj;
MyObjectBuilder() {
obj = new MyObject();
}
public MyObjectBuilder withI(int i) {
obj.i = i;
return this;
}
public MyObject build() {
return obj;
}
}
public class GenericBuilder {
public static <T extends BuilderType<S>, S> S getBuilder(Class<T> t) {
S s = null;
try {
s = (S) t.getDeclaredMethod("build" + t.getSimpleName(), null)
.invoke(null, null);
} catch (Exception e) {
e.printStackTrace();
}
return s;
}
}
the statement s=(S)t.get… in my GenericBuilder gives a cast warning: Unchecked Cast from Object to S, is there a way to eliminate it??
There is no way to eliminate the warning because
Sis not a real type. By runtime it will get erased to its upper bound, which isObjectin your case. So the “downcast” isn’t actually doing anything. You can check theMethod‘s return type by calling the appropriate method, and then do a reflective downcast (not very helpful for your scenario). Type safety cannot possibly be achieved when you dynamically fetch a method at runtime.