Как правильно создать динамический прокси-класс, основанный на правильном классе? - PullRequest
0 голосов
/ 29 июня 2018

У меня есть интерфейс, определенный следующим образом:

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.

Как мне это исправить?

Обратите внимание, что я могу изменить только класс CacheProbe, чтобы это исправить. Cache, AbstractCache, RealTimeCache, CacheLoader и эти две последние строки неизменяемы.

1 Ответ

0 голосов
/ 29 июня 2018

Однако я не понимаю, как это возможно, поскольку сгенерированный динамический прокси-класс основан на Cache.

Да, документы для java.lang.reflect.Proxy говорят

Proxy предоставляет статические методы для создания динамических прокси-классов и экземпляров, а это также суперкласс всех динамических прокси-классов, создаваемых этими методами .

(выделение добавлено)

Таким образом, вы не можете использовать Proxy для создания (экземпляра) подкласса произвольного класса по вашему выбору.

Как мне это исправить?

Вы можете создать обычный подкласс RealTimeCache и вернуть его экземпляр. Proxy предназначен в первую очередь для обслуживания интерфейсов, которые не известны до времени выполнения, и в этом случае единственным способом взаимодействия с ними в любом случае является тип интерфейса. Это не твой сценарий.

Если необходимо, вы можете реализовать такой подкласс в терминах MethodCountInvocationHandler, точно так же, как ваш прокси-класс, но я уверен, что будет проще реализовать любой инструмент, который предполагается предоставить напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...