Java – recursive type parameters for almost circular type binding
I have the following two interfaces:
/** * A marker interface to denote that an object implements a view on some other object. * * @param <T> The type of object that is viewed */ public interface View<T extends Viewable<View<T>>> { }
/** * An interface for objects that are viewable via a view. * * @param <T> The type of viewable object */ public interface Viewable<T extends View<?>> { public void addViewCallback(final T view); public void removeViewCallback(final T view); }
I want to do the following:
>The type parameter of view (called (a)) should be visual view (a). > The visual type parameter (called (b)) should be a view that can be viewed through the same visual (b)
I think I've finished limiting views, but how do I visualize them? What I get now is compilation, but it doesn't provide enough protection
I can't make something I don't want to accept right now, but I can make something I want if it helps:
>Public class hand implements < handview > > public interface handview extension view < hand >
Solution
As @ Simon Andr é Forsberg discussed, programming too defensive is often an unnecessary waste of time, and we should trust our own statements
However, for fun, here is a solution that enforces all restrictions on class / interface declarations at compile time
statement
View interface:
public interface View<T extends Viewable<T,?>> {}
>Here, we just want to ensure that the type parameter is visible. > The parameters of the second type need not be restricted, because the declaration of viewable will not allow visual < T,? > If so? Itself is not view < T >
Visual interface:
public interface Viewable<T extends Viewable<T,?>,V extends View<T>> { public void addViewCallback(final V view); public void removeViewCallback(final V view); }
>Here, t needs to be declared visible because we use it as the type parameter of view < T > At the end of the line. > As before, no restrictions? Because after we say, the parameter of the second type needs to be a view < T > if the parameter of the first type is t
usage
public class Hand implements Viewable<Hand,HandView> { @Override public void addViewCallback(HandView view) {} @Override public void removeViewCallback(HandView view) {} } public interface HandView extends View<Hand> { }