1

上下にクリックできる2つのボタンとともにテキスト編集コントロールを表示するカスタムUIコンポーネント(Android上)を作成しようとしています。上に移動すると編集コントロールの数値が増加し、下に移動すると減少します。

このクラスを数値型でジェネリックにしたい、つまりクラスを int 型と float 型に特化したい。

この素敵なJava Generics Tutorialを読んでいますが、私の特定の実装はコンパイルされていないようです。これが私が持っているものです:

public class NumberPicker<T> extends LinearLayout implements OnClickListener,
        OnFocusChangeListener, OnLongClickListener {

    public interface OnChangedListener<T> {
        void onChanged(NumberPicker<T> picker, T oldVal, T newVal);
    }

    public interface Formatter<T> {
        String toString(T value);
    }

    // Error: Cannot make a static reference to the non-static type T
    public static final NumberPicker.Formatter<T> TWO_DIGIT_FORMATTER =
            new NumberPicker.Formatter<T>() {
                public String toString(T value) {
                        // Do something with T value
                }
        };
}

の宣言で次のコンパイラ エラーが発生しますTWO_DIGIT_FORMATTER

非静的型 T への静的参照を作成できません

誰かが構文を手伝ってくれませんか。C++ から来た私は、ジェネリックを十分に理解しており、2 つの違いのいくつかを認識しています。構文のヘルプが必要です。

私はに変更しようとしました:

        // "Syntax error on token "int", Dimensions expected after this token"
    public static final NumberPicker.Formatter<int> TWO_DIGIT_FORMATTER =
            new NumberPicker.Formatter<int>() {
                public String toString(int value) {
                    return mFmt.toString();
                }
        };

これにより、「トークン「int」の構文エラー、このトークンの後にディメンションが必要です」が表示されます

4

4 に答える 4

2

これは構文とは関係ありません。タイプが のインスタンスに関連付けられているのに対し、タイプは のインスタンスに関連付けられていないという事実に関係Tいます。したがって、参照するタイプはありません。NumberPickerTWO_DIGIT_FORMATTERstaticNumberPickerT

于 2012-05-23T13:33:04.450 に答える
1

パラメータはインスタンスにT属しNumberPicker、各インスタンスは異なる値を持つことができるため、クラスの静的フィールドで依存することはできません。

public interface Formatter<T>インターフェイス メンバはデフォルトで静的であるため、で参照することもできません。

これを回避する 1 つの方法は次のとおりです。

  1. TWO_DIGIT_FORMATTER、定数であるため、パラメーターがバインドされている必要があります。考えてみると、この状況ではバインドされていないパラメーターはあまり意味がありません。
  2. Formatterインスタンスに渡すときにチェックされる、独自の個別のパラメーターを持つことができNumberPickerます。(これはすでに で暗黙的に行われていOnChangedListenerます。)

したがって、コードは次のようになります。

public class NumberPicker<T>  {

    public interface OnChangedListener<Y> { //
        void onChanged(NumberPicker<Y> picker, Y oldVal, Y newVal);
    }

    public interface Formatter<X> {
        String toString(X value);
    }

    public void setFormatter( Formatter<T> formatter ) { ... }

    public static final NumberPicker.Formatter<? extends Number> TWO_DIGIT_FORMATTER =
        new NumberPicker.Formatter<Number>() {
            public String toString(Number value) {
                    // Do something with T value
            }
        };

}

混乱を避けるために、インターフェース定義のTXを置き換えました。Yインターフェイスのパラメーターは、インターフェイスのパラメーターとは完全に分離されていますNumberPicker。異なる名前を付けることで、これはすぐに明らかになります。

于 2012-05-23T13:32:38.587 に答える
0

フィールドTWO_DIGIT_FORMATTERは静的フィールド、つまりクラス フィールドであり、特定のインスタンスに属していません。一方、型パラメーターは、具象型にバインドしTた特定のインスタンスを参照する場合にのみ解決されます。の型はインスタンスごとに変わるため、当然、クラス フィールドでは意味がありません。修飾子を削除してから、クラスのインスタンスを介してアクセスする必要があります。NumberPickerTTstaticTWO_DIGIT_FORMATTER

于 2012-05-23T13:34:04.483 に答える
0

静的メソッドでジェネリックを使用することはできません。Generic はインスタンスをパラメーター化し、 static はインスタンスではなくクラススコープです。

次のように変更できます (静的を削除):

public final NumberPicker.Formatter<T> TWO_DIGIT_FORMATTER = ...
于 2012-05-23T13:36:33.893 に答える