【问题标题】:Java Generics calling self class explanationJava泛型调用self类解释
【发布时间】:2015-04-27 05:15:06
【问题描述】:

Dave Syer 在包中写入了以下类,org.springframework.security.oauth2.config.annotation.builders

    public class ClientDetailsServiceBuilder<B extends ClientDetailsServiceBuilder<B>> extends
        SecurityConfigurerAdapter<ClientDetailsService, B> implements SecurityBuilder<ClientDetailsService> {
}

我在理解这段代码时遇到了一些困难。谁能在这里解释泛型的用法以及 Dave 想要在这里实现什么?

【问题讨论】:

  • dave syer 最适合这个问题,如果没有很好的答案,请尝试联系他
  • 从这个小 sn-p 判断,我猜这是一个流利的构建器 API 相当常见的习语。

标签: java spring generics


【解决方案1】:

它被称为递归类型绑定。这里B 是根据ClientDetailsServiceBuilder 定义的。但由于那是刚刚声明的类型,B 再次出现以满足类型参数。

我发现有用的更一般的解释:http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ106

这种模式的另一个很好的例子:

public interface Tree<T extends Tree<T>> {
    List<T> getChildren();
}

此定义使Tree 的子类型(实现)自动返回其类型参数的子类型,该类型参数必须是Tree,甚至可以是它们的实际类型。如果返回类型只是 List&lt;Tree&gt;,那么期望子类型的调用者可能必须强制转换。

【讨论】:

  • “这个定义使 Tree 的子类型(实现)自动返回其实际类型的子类型。”不必要。它们返回其类型参数的子代,不一定是它们的实际类型。
  • 你是对的,一个Tree 可以有另一种Tree 的孩子。我会稍微改变一下措辞。此外,更大的类型层次结构会使这里的事情变得混乱。只是认为这将是一个比 Spring 构建器更容易掌握的递归边界示例。
【解决方案2】:

通过使用class MyClass&lt;T extends MyClass&lt;T&gt;&gt;,您可以将任何子类的类型作为泛型类型访问。

这使您可以执行以下操作:

class MyClass<T extends MyClass<T>> {
    private int value;

    T withValue(int value) {
        this.value = value;
        return (T) this;
    }
}

class MySubclass extends MyClass<MySubclass> {
    private String name;

    public MySubclass withName(String name) {
        this.name = name;
        return this;
    }
}

MySubclass s = new MySubclass()
    .withValue(5)
    .withName("John Doe");

【讨论】:

  • "这使您可以执行以下操作:" 不,它没有。 (T) this 不安全。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多