几乎循环类型绑定的递归类型参数

ski*_*iwi 9 java generics bounded-wildcard

我有以下两个接口:

/**
 * 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>>> {

}
Run Code Online (Sandbox Code Playgroud)
/**
 * 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);
}
Run Code Online (Sandbox Code Playgroud)

我想强制执行以下操作:

  • View(调用(a))的类型参数应该是Viewable对该视图(a)的视图.
  • Viewable(call(b))的类型参数应该是a View,可以通过相同的可见(b)查看.

我认为我已经完成了这项工作View,但我将如何让它们发挥作用Viewable?我现在得到的是编译,但没有提供足够的保护.

我不能,截至目前,制定的东西得到接受,我不想,但是我可以制定我什么想要,如果这能帮助:

  • public class Hand implements Viewable<HandView>
  • public interface HandView extends View<Hand>

Sim*_*erg 7

由于你View是一个标记界面,而且你现在还没有制定任何你想要的东西,我View完全质疑界面的使用.你对自己施加了不必要的限制,除了麻烦之外什么都没有.

简化!

/**
 * An interface for objects that are viewable via a view.
 * 
 * @param <T>   The type of viewable object
 */
public interface Viewable<T> {
    public void addViewCallback(final T view);

    public void removeViewCallback(final T view);
}
Run Code Online (Sandbox Code Playgroud)


Jof*_*rey 5

正如@SimonAndréForsberg所讨论的那样,编程过于防守通常是不必要的浪费时间,我们应该相信我们自己的声明.

但是,为了它的乐趣,这里有一个解决方案,可以在编译时强制执行类/接口声明所需的所有限制.

声明

View接口:

public interface View<T extends Viewable<T, ?>> {}
Run Code Online (Sandbox Code Playgroud)
  • 在这里,我们只想确保类型参数是a Viewable.

  • 第二种类型的参数不需要限制,因为如果它本身Viewable不是a ,则声明不允许Viewable<T,?>存在.?View<T>

Viewable接口:

public interface Viewable<T extends Viewable<T,?>, V extends View<T>> {
    public void addViewCallback(final V view);
    public void removeViewCallback(final V view);
}
Run Code Online (Sandbox Code Playgroud)
  • 这里T需要声明为a,Viewable因为我们View<T>在行尾使用它作为类型参数.
  • 与之前相同,不需要限制?因为我们之后说第二个类型参数需要是a,View<T>如果第一个类型参数是a T.

用法

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> {
}
Run Code Online (Sandbox Code Playgroud)

  • +1只是为了让它编译. (2认同)