Я имел дело с hibernate, пытаясь выяснить класс времени выполнения за прокси-экземплярами, используя шаблон посетителя. Затем я придумал подход AbstractVisitable
, но мне интересно, будет ли он всегда давать правильные результаты.
Рассмотрим следующий код:
interface Visitable {
public void accept(Visitor v);
}
interface Visitor {
public void visit(Visitable visitorHost);
}
abstract class AbstractVisitable implements Visitable {
@Override
public void accept(Visitor v) {
v.visit(this);
}
}
class ConcreteVisitable extends AbstractVisitable {
public static void main(String[] args) {
final Visitable visitable = new ConcreteVisitable();
final Visitable proxyVisitable = (Visitable) Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class<?>[] { Visitable.class }, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
return method.invoke(visitable, args);
}
});
proxyVisitable.accept(new Visitor() {
@Override
public void visit(Visitable visitorHost) {
System.out.println(visitorHost.getClass());
}
});
}
}
Это делает ConcreteVisitable
, который наследует метод accept
от AbstractVisitable
. В c ++ я бы счел это рискованным, поскольку this
в AbstractVisitable может ссылаться на AbstractVisitable::this
, а не ConcreteVisitable::this
. Я волновался, что код при определенных обстоятельствах напечатает class AbstractVisible
. Тем не менее приведенный выше код выводит class ConcreteVisitable
, хотя я скрывал реальный тип за динамическим прокси (самый сложный случай, который я мог придумать). Гарантируется ли работоспособность подхода абстрактного посетителя выше или есть некоторые подводные камни в этом подходе?
Какие гарантии даются в Java в отношении указателя this
?