我正在尝试编写一个自定义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 ++我很了解通用,并且意识到两者之间的一些差异。我只需要语法帮助。
我尝试改为:
// "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“,此符号后面的维度”
答案 0 :(得分:2)
这与语法无关,它与您的类型T
与NumberPicker
的实例相关联的事实有关,而您的{{ 1}}是TWO_DIGIT_FORMATTER
,因此与static
的任何实例无关。因此,没有类型NumberPicker
可供其参考。
答案 1 :(得分:1)
T
参数属于NumberPicker
实例,每个实例可以具有不同的值,因此不能在该类的静态字段中依赖它。
也不能在public interface Formatter<T>
中引用它,因为接口成员默认是静态的。
解决此问题的一种方法是:
TWO_DIGIT_FORMATTER
,作为常量应该有参数绑定。当你考虑它时,在这种情况下,未绑定的参数并没有多大意义。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
}
};
}
我在接口定义中将T
替换为X
和Y
以避免混淆。接口的参数与NumberPicker
的参数完全分开。通过赋予它们不同的名称,这一点变得很明显。
答案 2 :(得分:0)
您的字段TWO_DIGIT_FORMATTER
是一个静态字段,即一个类字段,不属于任何特定实例。另一方面,仅当您引用已将T
绑定到具体类型的NumberPicker
的特定实例时,才会解析类型参数T
。 T
的类型随着不同的实例而变化,所以它自然在类字段上没有意义。您必须从static
中删除TWO_DIGIT_FORMATTER
限定符,然后您必须通过该类的实例访问它。
答案 3 :(得分:0)
您不能在静态方法中使用泛型。 Generic将对您的实例进行paremetrize,而static不是实例,而是类范围。
您可以将其更改为(删除静态):
public final NumberPicker.Formatter<T> TWO_DIGIT_FORMATTER = ...