代码之家  ›  专栏  ›  技术社区  ›  Richard Sand

Java工厂使用泛型和供应商接口,但仍然需要类型转换,有些地方不太正确

  •  1
  • Richard Sand  · 技术社区  · 6 年前

    我试图使用泛型和供应商来避免需要对静态工厂方法的结果进行类型转换,但失败了。我想我很接近了,有人能指出我做错了什么吗?

    这是参数化的界面 IManager :

    public interface IManager<C extends IConfigObject> {
    

    下面是一个抽象基类 ,其中包括静态工厂方法:

    public abstract class AbstractManager<C extends IConfigObject> implements IManager<C> {
        ....
        public static  <C extends IConfigObject> AbstractManager<C> getInstance(Supplier<? extends AbstractManager<C>> supplier) {
    

    接下来,这里是一个具体的实现,名为 参数化为 MyConfigObject项目 ,从而实现 IConfigObject :

    public final class MyManager extends AbstractManager<MyConfigObject> {
    

    最后,main()代码:

    Supplier<MyManager> supplier = MyManager::new;
    MyManager manager = (MyManager) AbstractManager.getInstance(supplier);
    

    如果没有强制转换,则会出现编译器错误:

    类型不匹配:无法从转换 AbstractManager到MyManager

    有什么建议吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Michael    6 年前

    您的问题在于: Supplier<? extends AbstractManager<C>> 通过使用通配符,您可以说“我不关心实际类型”,但您确实关心。

    这里的关键是首先使用两个类型参数,第二个依赖于第一个(我使用 M 对于“经理”):

    public static <C extends IConfigObject, M extends AbstractManager<C>>
        M getInstance(Supplier<M> supplier)
    {
        // ...
    }
    

    如果您不使用 C 在方法体中,可以将其重构为:

    public static <M extends AbstractManager<? extends IConfigObject>>
        M getInstance(Supplier<M> supplier)
    {
        // ...
    }