1

我正在尝试编写一个自定义 UI 组件(在 android 上),它将显示一个文本编辑控件以及两个可以向上或向下单击的按钮。向上增加编辑控件中的数字,向下减少它。

我希望这个类在数字类型上是通用的,即我想将这个类专门用于 int 和 float 类型。

我一直在阅读这个不错的Java 泛型教程,但我的特定实现似乎没有编译。这是我得到的:

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++,我对泛型理解得足够好,并且知道两者之间的一些差异。我只需要语法方面的帮助。

我尝试更改为:

        // "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. 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
            }
        };

}

我在接口定义中替换TXandY以避免混淆。接口的参数与参数完全分开,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 回答