Sometimes in Java, there is a case where you use a library that supplies a final class Car
and you wish it implemented some Vehicle
interface so that you could make Truck
and Bus
classes and treat them all as Vehicles in your code. But Car is final and it doesn't implement any interfaces.
How do I cast someone else's final Car
class to my Vehicle
interface so that I can pass it around like my other Vehicles? Every instance method on Vehicle would be 100% compatible with a similar method on Car in terms of instance method names, argument types, and return types. It would be equivalent from a Duck-Typing perspective.
I know I could make a MyCar extends Vehicle
wrapper class that just delegates each method call to an internal Car object. That would be The Java Way. But I'm just wondering if there is a technique to actually cast one class to an unrelated (but 100% compatible) interface. It's OK if the answer is evil.
Do it with a proxy:
import java.lang.reflect.Proxy;
public class DuckTyping {
static final class Car{
public void honk(){
System.out.println("honk");
}
}
interface Vehicle{
void honk();
}
public static void main(String[] a){
Car c = new Car();
Vehicle v = (Vehicle) Proxy.newProxyInstance(Vehicle.class.getClassLoader(), new Class[]{Vehicle.class}, (proxy, method, args) ->
Car.class.getMethod(method.getName(), method.getParameterTypes()).invoke(c, args)
);
v.honk();
}
}
Generic method:
static <T> T proxyCast(Object targetObject, Class<T> targetClass) {
return (T) Proxy.newProxyInstance(targetClass.getClassLoader(), new Class[]{targetClass}, (proxy, method, args) ->
targetObject.getClass().getMethod(method.getName(), method.getParameterTypes()).invoke(targetObject, args)
);
}
A final modifier in a class was made to not allow changes in its state so it's there's no way to modify the class.
Cast would only work for you if you extend from a parent class or implement to an interface, there's no other way (but you can't because the class is final)
In this case you have three options: 1. Wrapper (you mention). 2. Reflection (you can figure out useful information about the class and its methods in run time). 3. Create your own class.
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