首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我的方法如何接受任何类型的数字作为方法参数?(Java泛型)

我的方法如何接受任何类型的数字作为方法参数?(Java泛型)
EN

Stack Overflow用户
提问于 2017-03-13 22:27:38
回答 3查看 940关注 0票数 1

我的CustomNumber类扩展了Number类(实现了所有方法,但这里没有列出)。这个类有一个division方法,它的工作原理如下:我可以给它任何类型的Number参数,并且总是得到一个没有精度损失的计算。这就是为什么我在考虑双重价值。但在这种情况下,我不能使用其他任何东西调用此方法,只能使用双对象。我怎么才能使这个方法,任何可能是整个类100%泛型呢?

代码语言:javascript
运行
复制
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());
    }
}
EN

回答 3

Stack Overflow用户

发布于 2017-03-13 22:32:41

在这方面,Java是非常烦人的。

他们教条式地禁止操作符重载(尽管Scala有),所以你不得不把/编码成一个叫做divide或类似的方法,以此类推。

有关更多细节,请参阅BigInteger等任意精确库是如何实现的,并以此为基础构建您的解决方案。

Java的一个优点是,你可以不用使用BigDecimal,完全放弃你的想法。尽管在使用它执行复杂的数学运算时,您最终得到的代码实际上是不可读的。(由于这个原因,我求助于将C++与JNI一起使用)。

票数 0
EN

Stack Overflow用户

发布于 2017-03-13 23:02:58

如果这就是你想要的,那就不管用了:

代码语言:javascript
运行
复制
    CustomNumber<Integer> quotient = division(5, 3);

我们得到“类型不匹配:无法从CustomNumber<Double>转换为CustomNumber<Integer>”。原因很明显。即使你试图除以的数字被自动装箱到Integer中。

直接的解决方案是完全放弃泛型:

代码语言:javascript
运行
复制
public class CustomNumber extends java.lang.Number {

    // ...

    public static CustomNumber division(Number a, Number b) {
        return new CustomNumber(a.doubleValue() / b.doubleValue());
    }
}

现在,我们可以毫不费力地执行以下操作:

代码语言:javascript
运行
复制
    CustomNumber quotient = division(5, 3);
    System.out.println(quotient);

在您的类中使用适当的toString方法时,应该会显示以下内容:

代码语言:javascript
运行
复制
1.6666666666666667
票数 0
EN

Stack Overflow用户

发布于 2017-03-14 02:08:09

java.lang.Number提供的方法很少。例如,Division并不真正为每种类型做同样的事情。1.0d/2.0d0.5d,但1/20。所以你必须决定你要做什么。还要注意的是,double并不能准确地表示longBigInteger

要将各种形式的数字映射到您的通用解释,您需要一个适配器层。映射数值类型的方法可能不止一种。

代码语言:javascript
运行
复制
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();
    }
}

您可能想要有一个适配器,用于处理银行家舍入的相同类型。我甚至不想考虑如何实现这一点。或者在饱和算术上是满的。所以这是一个保留可选实现的符号(仍然除以零):

代码语言:javascript
运行
复制
    @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;
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42766091

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档