java复合设计模式与泛型

时间:2011-10-10 10:48:11

标签: java generics

我有两个通用的接口,IComparable<T>,方法public boolean gt(T t)ICombinable<T>,方法public T combine(T t),第三个接口IPreferenceValue<T>扩展这两个接口,即IPreferenceValue<T> extends IComparable<T>, ICombinable<T>,以便类型T的首选项值可以与其他T进行比较和组合。我有两个具体的IPreferenceValue实现,一个是单值实现:IntegerValue implements IPreferenceValue<IntegerValue>,另一个是偏好值列表:PreferenceVector<S extends IPreferenceValue<S>> implements IPreferenceValue<PreferenceVector<S>>

在其他地方我有一个在IPreferenceValues上执行各种操作的算法,我想通过接口以相同的方式处理单值和列表值的Preference值,比如Composite Design Pattern。我还希望有某种类型的Factory可以根据某个参数创建IPreferenceValues,即创建一个单值对象,或者创建一个列表值对象。但是当我创建这些PreferenceValues时,我不关心类型Parameter,我只想创建IPreferenceValue类型的对象,工厂将返回具体实现 - 并且只使用该接口与对象进行交互。

但是我在使用它时遇到了一些困难。首先,如果我使用原始类型IPreferenceValue声明我的值,我会收到这些警告 - “IPreferenceValue is a raw type. References to generic type IPreferenceValue<T> should be parameterized”。这些警告是否可以避免?在其他地方,我将它们声明为IPreferenceValue<?>,我收到以下错误:The method gt(capture#6-of ?) in the type IComparable<capture#6-of ?> is not applicable for the arguments (IPreferenceLevel<capture#7-of ?>)。任何建议或指示非常感谢...

编辑: 这是我得到第二个错误(The method gt(capture#12-of ?) in the type IComparable<capture#12-of ?> is not applicable for the arguments (IPreferenceLevel<capture#13-of ?>)

的地方
private IPreferenceLevel<?> calculateMinValue()
{
    IPreferenceLevel<?> min = null;
    for (IPreferenceLevel<?> value : tupleToValueMap.values())
    {
        if ((min == null) || (min.gt(value).equals(Comparison.TRUE)))
        {
            min = value;
        }
    }
    return min;
}

然而,即使我为此方法输入了一个类型,即,如果我重写如下 -

private <X> IPreferenceLevel<X> calculateMinValue()
{
    IPreferenceLevel<X> min = null; ...

这仍然无法编译 - The method gt(X) in the type IComparable<X> is not applicable for the arguments (IPreferenceLevel<capture#10-of ?>)

1 个答案:

答案 0 :(得分:1)

您没有给出足够的关于特定错误案例的背景信息,以便能够明确指出问题所在。所以我必须提供更多一般性的指示。

首先,原始类型警告是正确的。原始类型可能只是为了向后兼容而存在,你永远不应该在新代码中使用它们。 IPreferenceValue始终具有通用类型 - 如果您不知道它是什么并且不关心,请将其作为IPreferenceValue<?>返回,就像您已经完成的那样。这很好,基本上是您不了解/关心参数的通信。 (当然,如果您知道它可能是什么,那么无论如何都要提供更具体的参数。)

第二个错误似乎合法 - 您需要传递T,但是您尝试传入IPreferenceValue<T>

但是,一旦你解决了这个问题,你仍然会遇到问题。潜在的错误以完全不同的方式发生,并且对于泛型而言并不太常见。您有IPreferenceValue<?>的引用,并且您尝试调用其gt方法,该方法定义为T。但是你刚才说你完全不知道T对于那个对象是什么(这就是你使用通配符的原因) - 如果你不知道通用参数是什么,你怎么能传入< em>任何到它并知道它的类型正确吗?

具体来说,您试图将tupleToValueMap的内容相互比较。为了合法地执行此操作,其通用类型参数必须相同 - 您如何将IPreferenceLevel<IntegerValue>IPreferenceLevel<PreferenceVector<S>>进行比较?

因此,您应该更具体地声明tupleToValueMap的类型,为优先级而不是?提供具体的通用参数。如果事实证明你不能这样做,因为你在那里放置了多种类型的偏好级别 - 那么编译器错误是正确的,你不能安全地将它们相互比较。< / p>