3

データのメタタイプを表す Type インターフェイスがあります。パラメータは、データを表すために使用される 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()参照する方法はありますか? それは、コードを私が望むよりもはるかに複雑にしています。TypeValue

システム内の数値を表す単純な型を想像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;

常にBigDecimal を返すコンパイル時の安全性get()を実現したいと考えています。

BigDecimal bar = foo.get();

そうすれば、特定の Type の Java 表現を変更する必要がある場合 (たとえば、上記のコードのNumericType<Number>代わりに作成NumericType<BigDecimal>したい場合は、コンパイル時に失敗します。しかしValue、そのget()メソッド宣言が境界の境界を参照できるTypeように記述する方法パラメータ?Value<J, Type<J>>読むのは本当に厄介です:

Value<BigDecimal, NumericType> foo;

もっと良い方法があることを願っています。

4

2 に答える 2

0

私が確認する。Java でそれを行うことはできません。さらに、特定の NumericType が BigDecimal を内部表現として使用していることを隠すことに関心がある場合は、専用オブジェクトを使用して必要な操作の完全な抽象化を実装する方が簡単で堅牢です。これらの操作のみを使用してオブジェクトを操作する場合、内部表現を変更して、このクラスの内部のみが変更されるようにすることができます。

  1. 必要な操作を正確に定義することができます
  2. 必要な操作のセットが減るため、内部表現を簡単に調整できます。

これは基本的な 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));
于 2013-11-08T20:09:31.857 に答える
0

これが、ワイルドカードが発明された理由です。「? extends」ワイルドカードを使用します。 public interface Value<J, T extends Type<? extends J>> {...}

于 2013-11-12T18:10:04.883 に答える