Java.lang.reflect.Proxy returning another proxy from invocation results in ClassCastException on assignment

时光怂恿深爱的人放手 提交于 2019-12-04 04:45:26

Class.getInterfaces() returns only the interfaces DIRECTLY implemented by the class. You need a transitive closure to optain all the interfaces.

UPDATE

Example:

private static Class<?>[] getInterfaces(Class<?> c) {
    List<Class<?>> result = new ArrayList<Class<?>>();
    if (c.isInterface()) {
        result.add(c);
    } else {
        do {
            addInterfaces(c, result);
            c = c.getSuperclass();
        } while (c != null);
    }
    for (int i = 0; i < result.size(); ++i) {
        addInterfaces(result.get(i), result);
    }
    return result.toArray(new Class<?>[result.size()]);
}

private static void addInterfaces(Class<?> c, List<Class<?>> list) {
    for (Class<?> intf: c.getInterfaces()) {
        if (!list.contains(intf)) {
            list.add(intf);
        }
    }
}

You may also need to "unwrapp" the proxies that are passed as arguments.

@maurice-perry's solution worked great for me and I have voted for it, but I did also want to point out that there are library implementations of the needed method.

I ended up implementing this solution with the Apache Commons library method ClassUtils.getAllInterfaces():

...
import org.apache.commons.lang3.ClassUtils;
...

private static Class<?>[] getAllInterfaces(Object object) {
    final List<Class<?>> interfaces =
        ClassUtils.getAllInterfaces(object.getClass());

    return interfaces.toArray(new Class<?>[interfaces.size()]);
}

It works great for that magical second argument in newProxyInstance:

Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, 
                       InvocationHandler h)

There is also a Guava approach using:

final Set<TypeToken> tt = TypeToken.of(cls).getTypes().interfaces();

But then you have to figure out howto convert Set<TypeToken> to Class<?>[]. Trivial perhaps, if you're a Guava buff, but Apache's is ready for use.

Both of these were noted in this related thread, get all (derived) interfaces of a class.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!