如何正确生成基于正确类的动态代理类?

时间:2018-06-29 19:30:32

标签: java generics casting dynamic-proxy

我的接口定义如下:

$dates1
[1] FALSE FALSE FALSE

$dates2
[1] FALSE FALSE FALSE

然后是实现以上内容的抽象类:

public interface Cache {
}

然后从上面继承的具体类:

public abstract class AbstractCache implements Cache {
}

然后定义另一个类,如下所示:

public class RealTimeCache extends AbstractCache {
}

我有一个使用上述所有内容的类,如下所示:

public class CacheProbe {
    public static <T> T probe(T base) {
        return (T) Proxy.newProxyInstance(
                base.getClass().getClassLoader(),
                new Class[]{Cache.class},
                new MethodCountInvocationHandler(base) // I am not mentioning this class as it's irrelevant
        );
    }
}

最后,引起问题的行(位于上述类之外):

public class CacheLoader<T extends Cache> {
    public T load() {
        T result = getResult(...);
        CacheProbe x = new CacheProbe(result);
        return x.probe();
    }
}

问题是,在运行时,上面提到的最后一行引发了以下异常:

final CacheLoader<RealTimeCache> cacheLoader = getNewLoader(); //Method of this method is irrelevant and unchangeable
RealTimeCache x = cacheLoader.load(); //This is the line which is causing a runtime issue

但是我看不到这是怎么回事,因为生成的动态代理类基于java.lang.ClassCastException: com.sun.proxy.$Proxy57 cannot be cast to RealTimeCache

我该如何解决?

请注意,我只能更改Cache类以解决此问题。 CacheProbeCacheAbstractCacheRealTimeCache,最后两行是不可更改的。

1 个答案:

答案 0 :(得分:1)

  

但是我看不到这是怎么回事,因为生成的动态代理类基于Cache

是的,java.lang.reflect.Proxy的文档说

  

Proxy提供了用于创建动态代理类和实例的静态方法,并且它也是由这些方法创建的所有动态代理类的超类

(添加了重点)

因此,您不能使用Proxy创建您选择的任意类的子类(的实例)。

  

我该如何解决?

您可以创建RealTimeCache的普通子类,并返回其实例。 Proxy主要用于运行时才知道的接口,在这种情况下,与它们进行交互的唯一方法是接口类型。那不是你的情况。

如有必要,您可以像代理类一样使用MethodCountInvocationHandler来实现这样的子类,但是我敢肯定,实现应该直接提供的任何工具会更容易。 / p>