I’m trying to write a custom UI component (on android) that will display a text edit control along with two buttons which can be clicked up or down. Up increments the number in the edit control and down decrements it.
I’d like this class to be generic on the numeric type i.e. i’d like to specialize the class for int and float types.
I’ve been reading this nice Java Generics Tutorial but my particular implementation doesn’t seem to compile. Here’s what I have got:
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
}
};
}
I’m getting the following compiler error in the declaration of the TWO_DIGIT_FORMATTER:
Cannot make a static reference to the non-static type T
Can someone please help me with the syntax. Coming from C++ I understand generic well enough and am aware of some of the differences between the two. I just need help with the syntax.
I tried changing to:
// "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();
}
};
This gives “Syntax error on token “int”, Dimensions expected after this token”
The
Tparameter belongs to aNumberPickerinstance, each instance can have a different value to it, so it can’t be relied on in a static field of the class.Nor can it be referenced in the
public interface Formatter<T>, as interface members are by default static.One way to work around this is:
TWO_DIGIT_FORMATTER, being a constant should have the parameter bound. When you think about it, an unbound parameter doesn’t really make much sense in this situation.Formattercan have its own separate parameter, checked when you pass it to aNumberPickerinstance. (This is already done implicitly inOnChangedListener.)So your code will be something like this:
I replaced
TwithXandYin the interface definitions to avoid confusion. The parameter of the interfaces is completely separate from the parameter ofNumberPickerBy giving them different names this becomes readily apparent.