简体   繁体   English

缩小继承的返回类型(涉及泛型)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM