依赖Java类型的Java通用参数

时间:2013-10-10 14:17:46

标签: java generics

我有一个表示数据元型的接口类型。该参数指示将用于表示数据的Java类型:

public interface Type<J> {
    boolean isAssignableFrom(@NotNull Type ts);

    /**
     * Gets the Java class of the representation of this type.
     */
    Class<? extends J> getValueType();
}

我还有一个表示该类型实例的值接口:

public interface Value<T extends Type> {
    <E> E get();

    @NotNull
    T getType();
}

我想要的是让Value接口强制执行Type接口上声明的参数。换句话说,我希望get()方法声明它的返回类型必须在<J>的范围内。但是,如果不将<J>添加到Value界面,我无法提出任何方法:

public interface Value<J, T extends Type<J>> {
    J get();

    @NotNull
    T getType();
}

有没有办法让get()引用其Type的有界参数而不将其添加到Value界面?它使代码真的比我想要的复杂得多。

想象NumericType这是一个简单的类型来表示系统中的数字(除了在运行时,还有更复杂的动态类型不存在,这是元编程的乐趣):

/** A static type representing some kind of number. */
public class NumericType implements Type<BigDecimal>
{
    public static final NumericType NUMERIC_TYPE = new NumericType();


    public boolean isAssignableFrom(@NotNull Type t)
    {
        // logic here
    }

    public Class<BigDecimal> getValueType() {
        return BigDecimal.class;
    }
}

它告诉调用者用于在系统中表示此类型的Java类型。如果我声明值为NumericType

Value<NumericType> foo;

我希望能够有get() 始终返回BigDecimal的编译时安全性:

BigDecimal bar = foo.get();

这样,如果我需要更改给定类型的Java表示(比方说,我想使NumericType<Number>而不是NumericType<BigDecimal>,上面的代码将在编译时失败。但是我怎么做写Value,使其get()方法声明可以引用Type有界参数的范围?Value<J, Type<J>>事情真的很难阅读:

Value<BigDecimal, NumericType> foo;

我希望有更好的方法。

2 个答案:

答案 0 :(得分:0)

我确认。在Java中不可能这样做。 此外,如果要隐藏给定的NumericType使用BigDecimal作为内部表示,那么使用专用对象实现所需操作的完全抽象将更简单,更健壮。如果只使用那些操作来操作对象,则可以更改内部表示,使得唯一的更改是此类的内部:

  1. 它允许精确定义所需的操作
  2. 由于所需的操作集合减少,因此可以轻松调整内部表示。
  3. 这是基本的OOP概念和KISS原则(Keep It Simple,Stupid)。

    class NumericType {
      private int value;
      public NumericType(int initial) {...}
      public NumericType add(NumericType operand) {...}
      ...
    }
    

    然后可以像这样使用

    NumericType bar = new NumeicType(1);
    bar = bar.add(new NumericType(1));
    

答案 1 :(得分:0)

这就是发明通配符的原因。使用“?extends”通配符:     public interface Value<J, T extends Type<? extends J>> {...}