冗余通用参数

我有这两个接口和类:

public interface Identifiable { T getId(); } public interface GenericRepository<T extends Identifiable, K> { T get(K id); } public class MyEntity implements Identifiable { private Long id; public Long getId() { return id; } } public class MyService { private GenericRepository myEntityRepository; } 

这一切都按预期工作。 但在我看来,GenericRepository(K)中的第二个generics参数是多余的。 因为我知道MyEntity是一个可识别的,我认为如果我最终能像这样使用它会很棒:

 public class MyService { private GenericRepository myEntityRepository; } 

但是我没有成功就尝试了不同的事情。 可能吗? 如果没有,为什么不呢?

更新:回答一些回复。 我认为编译器知道MyEntity中哪种类型是通用的。 例如:

 public class MyEntityGenericRepository implements GenericRepository { // compiles... } public class MyEntityGenericRepository implements GenericRepository { // compiler says: "Bound mismatch: The type MyEntity is not a valid substitute for the bounded parameter <T extends Identifiable> of the type GenericRepository" } 

我认为你不能省略它。 使用T extends Identifiable您想要说generics类型参数必须是可Identifiable 。 由于Identifiable是generics类,因此您还需要提及其generics类型参数(如果您希望按照规则进行播放 – 如果省略它,则由于向后兼容性规则,您将失去GenericRepository所有generics类型安全性)。 另请注意, K实际上用作GenericRepository.get的参数类型。 由于该类型可能与T不同,因此您需要通过将其声明为GenericRepository另一个generics类型参数来满足编译器。 否则编译器无法知道K是什么。

从GenericRepository类的角度来看,这并不是多余的。 当它有像T get(K id) ,它无法知道它可以接受哪种类型的id参数。 你可以写下面的内容:

 interface GenericRepository> { T get(Object id); } 

现在您不必将Long作为类型参数编写,但是您无法检查在编译时是否正确使用了get方法。 因此类型变量用于特定目的。

至于字段声明,当你有generics类型时,你必须指定它使用的所有类型变量。 当然,如果语言能够理解其中一个参数值可以从另一个参数值中推断出来,那么你可以说它会很整洁,但这是值得商榷的。

除了引入只改进GenericRepository的接口之外,你无能为力

  public interface LongKeyedRepository> extends GenericRepository { { //No new methods need to be defined } 

然后你就可以拥有

 private LongKeyedRepository myEntityRepository; 

等等

如果我没有弄错,那么generics将被编译为好像它们只是Object 。 现在语法被(硬)检查以确保你没有把苹果与橘子一起使用,因为在Java的初始设计之后添加了generics。 这就是为什么generics如此受限……

它可以使用(即编译)

 public interface GenericRepository { T get(T id); } 

但它仍然说可识别是一种原始类型,它应该是参数化的。

希望能帮助到你。

为什么你不能删除第二个K,

 public interface GenericRepository, K> { 

因此,我们不应该像上面那样拥有它

 public interface GenericRepository> { 

通过这个我们可以做你想做的事。