【问题标题】:composition of generic types in javajava中泛型类型的组成
【发布时间】:2013-11-28 05:25:27
【问题描述】:

假设我正在定义一个类 User,它有一个扩展 Principal 的泛型类型

public abstract class User<P extends Principal> {
}

我有一个动作基类,应该用用户参数化:

public abstract class Action<U extends User<Principal>> {
}

这两个类在 muy 代码库中。现在,我想在特定的应用程序上使用它们,所以我为 Principal 和 User 创建了一个实现:

public class MyPrincipal implements Principal {
    public String getName() {
        return "Administrator";
    }
}

public class MyUser extends User<MyPrincipal>{
}

拥有用户后,我想在操作中使用它

public class MyAction extends Action<MyUser>{
}

最后一个类不能编译。它抱怨说:

Bound mismatch: The type MyUser is not a valid substitute for the bounded parameter <U extends User<Principal>> of the type Action<U>

我想要强制所有扩展 MyAction 的类都应该使用扩展 User 的对象进行参数化,并且还应该使用实现 Principal 的对象进行参数化。我错过了什么?

【问题讨论】:

    标签: java generics


    【解决方案1】:

    目前,Action 课程的界限是 - U extends User&lt;Principal&gt;。由于MyUser 不是扩展User&lt;Principal&gt;,而是扩展User&lt;MyPrincipal&gt;,因此它不会像您预期的那样工作。 User&lt;MyPrincipal&gt; 不是 User&lt;Principal&gt;(不同的类型)。

    您可以在 Action 类中引入另一个类型参数,并在 U 的范围内使用它:

    public abstract class Action<P extends Principal, U extends User<P>> {
    }
    

    现在,您可以像这样创建MyAction

    public class MyAction extends Action<MyPrincipal, MyUser>{
    }
    

    或者您也可以使用通配符绑定修改您的类:

    public abstract class Action<U extends User<? extends Principal>> {
    }
    

    这样你就不需要其他类型参数了:

    public class MyAction extends Action<MyUser>{
    }
    

    参考资料:

    【讨论】:

    • 是的,这两个选项都有效。但我的问题是,为什么我不能将其定义为 Action>
    • @JoseLMartinez-Avial B'coz 你还没有声明类型参数P。如果类型参数位于顶层,则称为为类声明类型参数,而不是在嵌套时声明。并且在使用类型参数作为边界之前,您必须声明它自己。
    【解决方案2】:

    Action 的签名更改为此(我在 Eclipse 中测试并编译):

    public abstract class Action<U extends User<? extends Principal>>
    

    通过这样做,您是在说任何类型的 Principal 都可以,而不仅仅是基本类型的 Principal 对象(当然不能实例化)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-01
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多