Java中的递归接口类型参数

时间:2018-03-27 19:44:58

标签: java generics interface

我试图理解interface源代码中的递归apache thrift定义

 public interface TBase<T extends TBase<?, ?>, F extends TFieldIdEnum> extends Comparable<T>, Serializable {

据我所知TBase是一个包含类型参数TF的界面。

T的约束条件是它还必须扩展TBase,其类型参数包含任何类型。

我感到困惑的是什么是终止TBase

说我有

public class TBaseImpl<A, B> implements TBase<A, B>

A必须是TBase

所以必须有另一个类实现A

public class TBaseImplA<C, D> implements TBase<C, D>

C必须是TBase

所以必须有另一个类实现C

这种情况永远存在。

所以我的问题是

  1. TBase
  2. 的终止条件是什么
  3. 这种递归定义有什么好处?
  4. 有人能指出我的方向吗?

    由于

1 个答案:

答案 0 :(得分:4)

  

所以必须有另一个类实现A

这不一定是真的。使用这种类型的递归边界,在创建子类型时有两种可能的方法来满足约束。

  1. 使用相同或更严格的边界声明您自己的类型参数。这会给这个类的用户选择type参数带来负担。
  2. public class TBaseImpl<A extends TBase<A, B>, B extends TFieldIdEnum> implements TBase<A, B>
    

    或更可能

    public class TBaseImpl<A extends TBaseImpl<A, B>, B extends TFieldIdEnum> implements TBase<A, B>
    
    1. 传递与您定义的相同的类以满足原始范围。
    2. public class TBaseImpl<B extends TFieldIdEnum> implements TBase<TBaseImpl, B>
      

      此模式的一个好处是能够限制意图接受同一类的另一个实例的方法的参数,例如:

      public void example(T other)
      

      这是(在Java中)Curiously Repeating Template Pattern

      通常,实现/重写方法必须完全匹配参数类型和参数顺序。但是这种模式允许您通过缩小类型参数来缩小类型。例如。在这种情况下TBaseImpl中的这种方法只需要TBaseImpl而不是更广泛的TTBase。在这样的课堂上,课堂与自身之间存在关系。

      另一个好处是方法链,其中方法返回this以允许

      obj.method1().method2().method3()
      

      通过这种方式,可以声明链接方法返回T,例如TBase<TBaseImpl>变量可以调用这些方法,每个方法返回一个TBaseImpl,可以在其上调用另一个方法。

      T method1();  // in TBase
      
      @Override
      TBaseImpl method1(); // in TBaseImpl
      

      顺便提一下,如果您尝试声明一个类型变量是枚举的子类型,那么这不是必需的,因为enumfinal并且无法扩展。在接口中删除F并让实现类直接使用枚举更简单。