私は現在、次のタイプで作業しています。
// A Field whose values are of type V.
interface Field<V> {
public V getValue();
}
// A Field whose values are of type V and that has a LabelProvider for those values.
interface LabelField<V> extends Field<V> {
public LabelProvider<V> getLabelProvider();
}
これらは図書館からのものであり、私はそれらを変更することはできません。これはおそらく関係ありませんが、LabelProviderは基本的に、タイプVの値を文字列に変換するクラスです。
次に、次のようなインターフェイスを提供するクラスを作成します。
// A Wrapper class for Fields of values V
interface IWrapper<V, F extends Field<V>> {
public F getField();
public V getValue();
public String getLabel();
}
クラスはフィールドをラップし、そのユーザーがフィールドから値を取得できるようにしますが、ラベルの取得などの他の機能も提供します。これが私が持っているものです:
public class Wrapper<V, F extends Field<V>> {
private F field;
private LabelProvider<V> labelProvider; // Converts from V to String
// Since we have no guarantee that F has a LabelProvider, one is explicitely supplied.
public Wrapper(F field, LabelProvider<V> labelProvider) {
this.field = field;
this.labelProvider = labelProvider;
}
private String getLabel() {
return labelProvider.getLabel(field.getValue());
}
public F getField() {
return field;
}
public V getValue() {
return field.getValue();
}
}
これらの2つのジェネリック型が必要かどうかはわかりませんが、この時点までは問題ありません。理想的には、Wrapper>を使用して、FとVの両方にアクセスできるようにすることをお勧めします。これは不可能であり、上記がこれを行う正しい方法だと思いますか?
これが本当の問題です。
LabelFieldタイプのより具体的なコンストラクターが必要です。これは次のようになります。
public Wrapper(LabelField<V> labelField) {
// Use the field's own label provider
this(labelField, labelField.getLabelProvider());
}
この場合、labelproviderをフィールドから抽出できます。しかし、コンパイラはこれを気に入らず、次のエラーが発生します。
The constructor Wrapper<V,F>(LabelField<V>, LabelProvider<V>) is undefined
同じ型を使用するこのメソッドはコンパイルしますが:
public static <X> void test(LabelField<X> lf) {
LabelProvider<X> lp = lf.getLabelProvider();
new Wrapper<X, LabelField<X>>(lf, lp);
}
2番目のコンストラクターがコンパイルされないのはなぜですか?
これがSSCEです:http://pastebin.com/UqLJhJA7