[英]Narrowing return types on inheritance (generics involved)
I'm wrestling with a bit of weird generics behavior regarding being able to "narrow" return types when subclassing. 关于在子类化时能够“缩小”返回类型,我正在努力解决一些奇怪的泛型行为。 I managed to reduce the problem to the following set of classes: 我设法将问题减少到以下几组:
public class AbstractIndex {
}
public class TreeIndex extends AbstractIndex {
}
public interface IService<T extends AbstractIndex> {
}
public interface ITreeService extends IService<TreeIndex> {
}
public abstract class AbstractServiceTest<T extends AbstractIndex> {
abstract <V extends IService<T>> V getService();
}
public class TreeServiceTest extends AbstractServiceTest<TreeIndex> {
@Override
ITreeService getService() {
return null;
}
}
The problem is that Java warns when I try to narrow the return type of getService
to ITreeService
. 问题是当我尝试将getService
的返回类型缩小到ITreeService
时,Java会发出警告。 The warning is 警告是
Type safety: The return type ITreeService for getService() from the type TreeServiceTest needs unchecked conversion to conform to V from the type AbstractServiceTest 类型安全:从TreeServiceTest类型返回类型ITreeService for getService()需要未经检查的转换以符合类型AbstractServiceTest中的V
Why is not ITreeService a valid narrowing type for getService
? 为什么不ITreeService一个有效的缩小型getService
?
EDIT: changed error to warning 编辑:将错误更改为警告
Because I think you meant to say this: 因为我认为你的意思是:
public abstract class AbstractServiceTest<T extends AbstractIndex> {
abstract IService<T> getService();
}
There's no purpose to making the separate V
type variable, other than adding constraints that your subclasses can't fulfil. 除了添加子类无法实现的约束之外,创建单独的V
类型变量没有任何意义。 :-P :-P
And if you want to have AbstractServiceTest
s with different V
s for the same T
, you can do this: 如果你想让相同T
不同V
s的AbstractServiceTest
,你可以这样做:
public abstract class AbstractServiceTest<T extends AbstractIndex, V extends IService<T>> {
abstract V getService();
}
public class TreeServiceTest extends AbstractServiceTest<TreeIndex, ITreeService> {
@Override
ITreeService getService() {
return null;
}
}
public class AnotherTreeServiceTest extends AbstractServiceTest<TreeIndex, AnotherTreeService> {
@Override
AnotherTreeService getService() {
return null;
}
}
EDIT: However, it makes sense only if you also use V
in some other place, such as: 编辑:但是,只有在其他地方使用V
时才有意义,例如:
public void setService(V service) { ... }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.