我有一个表示数据元型的接口类型。该参数指示将用于表示数据的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;
我希望有更好的方法。
答案 0 :(得分:0)
我确认。在Java中不可能这样做。 此外,如果要隐藏给定的NumericType使用BigDecimal作为内部表示,那么使用专用对象实现所需操作的完全抽象将更简单,更健壮。如果只使用那些操作来操作对象,则可以更改内部表示,使得唯一的更改是此类的内部:
这是基本的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>> {...}