Suppose I have this Foo
class, which has generic type variable E
that extends Number
. Since each Number
object should have a double value, when instantiating a new instance of type E
I would like to give it a double value. Is it possible? How?
public class Foo<E extends Number> {
...
public void someMethod() {
... // some computation
Class<E> typeClass;
E newInstance = typeClass.newInstance();
// Because every Number has a doubleValue(),
// I would like to give newInstance a double value, how?
}
}
Or should I just abandon the generic type variable, and use Double
instead? But I don't want to limit user's freedom of using Byte
or Integer
. Are these number classes interchangeable, ie, can Byte
cast to Double
in some way?
Thanks!!
EDIT:
I am implementing Dijkstra's algorithm with generics, which calculates the least weighted path. This means the edge labels can be accumulated in some way, and the most general class for this purpose that I can think of is Number
.
First of all, your assumption that
Since each Number object should have a double value, when instantiating a new instance of type EI would like to give it a double value.
is not correct.
For example, how can you instantiate a Integer with a double value 1.5? Should it instantiate by rounding? By truncating? I can very well define a subclass of Number that doesn't even support arbitrary integer, like the following one:
public static class Zero extends Number {
@Override
public double doubleValue() {
return 0;
}
@Override
public float floatValue() {
return 0;
}
@Override
public int intValue() {
return 0;
}
@Override
public long longValue() {
return 0;
}
}
How do you instantiate a Zero with a double value like 1.5?
Since there is no universal logic that can instantiate an arbitrary subclass of Number with an arbitrary double value (this is the reason why Number don't have an constructor with a double argument), the only reasonable way is to ask the client to provide a factory that can fabricate an instance of a subclass of Number given an arbitrary double value with custom logic that applies to that specific subclass. Like the following:
public class Foo<E extends Number> {
public static interface NumberFactory<T extends Number> {
T createByDoubleValue(double value);
}
private final NumberFactory<E> factory;
public Foo(NumberFactory<E> factory) {
this.factory = factory;
}
...
public void someMethod() {
... // some computation
// Because every Number has a doubleValue(),
// I would like to give newInstance a double value, how?
E instance = factory.createByDoubleValue(1.5);
}
}
To use Foo class, the client need to define the factory, like the following:
Foo<Float> foo = new Foo<>(new Foo.NumberFactory<Float>() {
@Override
public Float createByDoubleValue(double value) {
return new Float(value);
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.