Skip to content

Instantly share code, notes, and snippets.

@henkman
Last active August 29, 2015 14:26
Show Gist options
  • Select an option

  • Save henkman/0f6d6372a9d187f28ed2 to your computer and use it in GitHub Desktop.

Select an option

Save henkman/0f6d6372a9d187f28ed2 to your computer and use it in GitHub Desktop.
java ducktype class
/*
class Duck {
public void quack() { System.out.println("quack"); }
}
interface Quacker {
public void quack();
}
{
Object duck = new Duck();
Quacker quacker = DuckType.to(duck, Quacker.class);
quacker.quack();
}
*/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DuckType {
private static class CoercedProxy implements InvocationHandler {
private final Object object;
public CoercedProxy(Object object) {
this.object = object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return object.getClass()
.getMethod(method.getName(), method.getParameterTypes())
.invoke(object, args);
}
}
public static <T> T to(Object object, Class<T> iface) {
assert iface.isInterface() : "cannot coerce object to a class, must be an interface";
if (object.getClass().isInstance(iface)) {
return iface.cast(object);
}
for (Method method : iface.getMethods()) {
try {
object.getClass().getMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
throw new ClassCastException("Could not coerce object of type " + object.getClass() + " to " + iface);
}
}
return (T) Proxy.newProxyInstance(iface.getClassLoader(), new Class[]{iface}, new CoercedProxy(object));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment