java在继承期间获取泛型参数的泛型参数
如果是,我可以访问另一个泛型参数的泛型参数,而不指定它吗
下面的例子是根据我目前的情况简化的。省略所有成员和方法,因为它们与情况无关LibraryRepository
是一个JPA/Spring类型,它需要一个ENTITY
和一个ID
abstract class AbstractEntity<ID> {}
class ConcreteEntity extends AbstractEntity<Long> {}
interface AbstractRepository<ENTITY extends AbstractEntity<?????>> extends LibraryRepository<ENTITY, ?????> {}
//Desired declaration:
interface ConcreteRepository extends AbstractRepository<ConcreteEntity> {}
如果可能的话,不在AbstractRepository
上指定Long
,写什么来代替两个?????
出于问题范围的考虑,请回答有关泛型的问题,而不是如何以更好的方式实现spring存储库。不过,我很高兴在评论中得到有关这方面的提示
# 1 楼答案
也许这正是您试图避免的,但我认为您应该将
AbstractEntity
的泛型参数指定为AbstractRepository
中的参数,类似这样:我不知道编译器如何才能对
LibraryRepository
的泛型参数进行类型检查# 2 楼答案
关于泛型的一种(特别有用的)思考方式是它们将类型链接在一起。如果您声明了一个新的typevar并只在一个地方使用它,由于擦除,这实际上是无用的。在两个地方使用它,现在您已经告诉编译器您使用
T
的两个地方是链接的:它们可以是任何东西,只要它们是相同的东西这种思维方式在这里也提供了一些见解:很明显,你希望你的第一个
?????
链接到你的第二个?????
:使它们相等这样做的方法是声明一个新的typevar并使用它:
不幸的是,这意味着
AbstractRepository
现在获得了一个类型变量,我想您不希望发生这种情况不幸的是,如果没有类型变量,java无法链接类型
作为一般的经验法则,如果混合使用类层次结构(扩展事物实现事物的事物)和大量泛型,那么最终会出现大量泛型参数,其中一些参数会感觉像是干巴巴的违规行为。解决方案是要么接受它,要么不做这两件事中的一件(使用组合而不是继承,或者减少正在使用的类型变量,或者将它们移到方法中),或者使用一系列骇人的反射和“警告强制转换”(将内容强制转换为typevar,实际上不会进行任何类型检查,并且往往会在奇怪的地方导致
ClassCastException
的错误:在行中任何地方都没有强制转换,而不是有错误代码的地方。这导致了漫长而艰巨的错误查找练习