我的CustomNumber类扩展了Number类(实现了所有方法,但这里没有列出)。这个类有一个division方法,它的工作原理如下:我可以给它任何类型的Number参数,并且总是得到一个没有精度损失的计算。这就是为什么我在考虑双重价值。但在这种情况下,我不能使用其他任何东西调用此方法,只能使用双对象。我怎么才能使这个方法,任何可能是整个类100%泛型呢?
public class CustomNumber<T> extends java.lang.Number {
java.lang.Number value;
public CustomNumber(java.lang.Number value) {
this.value = value;
}
public static CustomNumber<Double> division(Number a, Number b) {
return new CustomNumber<>(a.doubleValue() / b.doubleValue());
}
}发布于 2017-03-13 22:32:41
在这方面,Java是非常烦人的。
他们教条式地禁止操作符重载(尽管Scala有),所以你不得不把/编码成一个叫做divide或类似的方法,以此类推。
有关更多细节,请参阅BigInteger等任意精确库是如何实现的,并以此为基础构建您的解决方案。
Java的一个优点是,你可以不用使用BigDecimal,完全放弃你的想法。尽管在使用它执行复杂的数学运算时,您最终得到的代码实际上是不可读的。(由于这个原因,我求助于将C++与JNI一起使用)。
发布于 2017-03-13 23:02:58
如果这就是你想要的,那就不管用了:
CustomNumber<Integer> quotient = division(5, 3);我们得到“类型不匹配:无法从CustomNumber<Double>转换为CustomNumber<Integer>”。原因很明显。即使你试图除以的数字被自动装箱到Integer中。
直接的解决方案是完全放弃泛型:
public class CustomNumber extends java.lang.Number {
// ...
public static CustomNumber division(Number a, Number b) {
return new CustomNumber(a.doubleValue() / b.doubleValue());
}
}现在,我们可以毫不费力地执行以下操作:
CustomNumber quotient = division(5, 3);
System.out.println(quotient);在您的类中使用适当的toString方法时,应该会显示以下内容:
1.6666666666666667发布于 2017-03-14 02:08:09
java.lang.Number提供的方法很少。例如,Division并不真正为每种类型做同样的事情。1.0d/2.0d为0.5d,但1/2为0。所以你必须决定你要做什么。还要注意的是,double并不能准确地表示long或BigInteger。
要将各种形式的数字映射到您的通用解释,您需要一个适配器层。映射数值类型的方法可能不止一种。
public interface CustomNumber<THIS extends CustomNumber<THIS>> {
THIS divide(THIS other);
}
public final class LongNumber extends CustomNumber<LongNumber> {
// (Note, you don't actually need to overload this,
// but it does prevent the likes of LongNumber.of(aDouble).)
public static LongNumber of(Long value) {
return new LongNumber(value);
}
public static LongNumber of(AtomicLong value) {
return new LongNumber(value);
}
private final Number value;
private LongNumber(Number value) {
this.value = value;
}
@Override public LongNumber divide(LongNumber other) {
return this.longValue() / other.longValue();
}
}您可能想要有一个适配器,用于处理银行家舍入的相同类型。我甚至不想考虑如何实现这一点。或者在饱和算术上是满的。所以这是一个保留可选实现的符号(仍然除以零):
@Override public SignPreservingLongNumber divide(
SignPreservingLongNumber other
) {
long dividend = this.longValue();
long divisor = other.longValue();
return (
dividend == Long.MIN_VALUE &&
divisor == -1
) ? Long.MAX_VALUE : dividend/divisor;
}https://stackoverflow.com/questions/42766091
复制相似问题