Java: How write a cast that specifies both a superclass and an interface?
-
22-09-2019 - |
Question
I have something like this going on in my Java program:
void f(Object o) {
g(o);
}
<T extends MySuperClass & MyInterface> void g(T x) {
...;
}
How can I cast o so that this works? There seems to be no way to specify both a base class and an interface in variable declarations without using generics. I don't think generics will work here, because o is being created dynamically using reflection, so its actual class is not known at compile time.
(Yeah, I know this is a weird thing to want to do. But I actually do need functionality from both the superclass and the interface. I guess I could do all of the type checking at runtime with instanceof, but that just seems so Java 1.4...)
Solution
It seems to be there is no way to invoke a "raw" generic method. But you can create an object of raw type (the following conversion is, obviously, unsafe):
void f(Object o) {
Caster<?> c = new Caster();
g(c.cast(o));
}
class Caster<T extends MySuperClass & MyInterface> {
public T cast(Object o) {
return (T) o;
}
}
OTHER TIPS
You can create a new inner class within the class containing f()
calling g()
static abstract class MyCastingClass extends MySuperClass implements MyInterface {}
Then you can cast:
g((MyCastingClass)o);
EDIT:
This doesn't appear to work though.
It allows your code to compile, and has no warnings, but at runtime, you'll get a ClassCastException
unless your object is actually an instance of MyCastingClass
You can use reflection to invoke g, similar to the below, but with more checks on picking the correct merhod, and handling exceptions:
Object dest_obj_containing_g = this; // Replace with your object.
Method[] methods = dest_obj_containing_g.getClass().getDeclaredMethods();
for (Method m : methods) {
if (m.getName().equals("g")) {
m.invoke(dest_obj_containing_g,o);
break;
}
}
Could it be something like
<T extends MySuperClass implements MyInterface>
I'm just guessing here...