Reputation: 3073
I have a class meant for holding numeric values that could be changed by the user through the GUI. The GUI has a TextField (of JavaFX) where they could write the desirable value.
Since I wanted this class to be flexible I made it using generics like this:
public class ConfigurableNumericField <T extends Number> {
private T value;
//...
public void setValue(T value){
this.value = value;
}
}
And I create an object like this:
ConfigurableNumericField <Integer> foo = new ConfigurableNumericField <> ( /*...*/ );
The problem is that the TextField returns a CharacterSequence
(that could be casted to String
). BUT even if all classes that inherit from Number
have the valueOf
method, Number
does not have it.
So when I try to setValue()
the String
from the TextField to the class itself. I get a java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number
.
How can I do this?
Upvotes: 1
Views: 1757
Reputation: 421100
The reason this may be problematic is that future / custom Number
implementations may not provide this method, since it's not part of the contract.
Here are two options that comes to mind:
Use reflection to invoke the setValue
method.
Use a couple of instanceof
checks and casts to cover the Numbers you need to support.
Upvotes: 1
Reputation: 533680
When generics you can make things so generic that they are not meaningful anymore.
In your case you need a setValue which will take a String so you can convert it to the appropriate type. The problem with this is there is no way to do this genericly as the generic type of foo
is not available at runtime.
I would have two subclasses, one for integers which uses a Long
and another which uses a Double
or BigDecimal
. This will support most of the Number types you are likely to need.
Upvotes: 2
Reputation: 198221
You really can't. All of the possible approaches end up involving special cases for each number type.
Upvotes: 1