【问题标题】:Replacing/Overriding Java "native" Classes?替换/覆盖Java“本机”类?
【发布时间】:2013-11-03 08:09:20
【问题描述】:

我正在使用 BigDecimals,我要求除以 0 不应导致 ArithmeticException,而是返回 0(奇怪的商业数学)。

这是一个相当新的要求,我们已经有相当多的代码,在很多地方都使用了BigDecimals。我不想遍历所有这些地方并实施零检查。这也不会帮助我使用 3rd 方库,它可能在内部使用 BigDecimals 并会抛出 ArithmeticExceptioninstead。

我还想设置默认精度/比例并更改 compareTo 方法以忽略小的舍入误差。

由于所有这些全局更改会创建大量“样板”代码,因此我想出了更改 BigDecimal 的实现的想法。我之前已经为其他 3rd 方类自己修复了某些错误。

我通过在同一个包中创建一个同名的类来替换这些类,就像第 3 方类一样,因为外部 jar 文件将在我自己的类之后加载,所以我能够替换它们。

但创建java.math.BigDecimal 并没有帮助我,因为似乎“本机”Java 类甚至在我自己的类之前就已加载。

假设我真的希望我的应用程序中的每一个BigDecimal 都有点不同,我如何才能替换“官方”BigDecimal?我可以这样做吗?会不会有其他一些我现在没有想到的技术问题?

【问题讨论】:

    标签: java overriding bigdecimal


    【解决方案1】:

    如果你想覆盖内置类,你必须把你的类放在"bootstrap" classpath 中。至于实际这样做是否明智(即您的更改将影响 整个 jvm)...

    【讨论】:

    • 这让我更近了一步,但似乎我必须为 all java 类设置此路径并提供一组全新的运行时,而不能只是替换一个班级。我正在考虑无论如何操作类加载器......
    • @noone - 为什么需要提供整个运行时?您只需将您的类放在运行时其余部分前面的引导类路径中(即-Xbootclasspath/p)。
    • 不适合我,因为它是一个非标准选项,我的 JVM 不支持它。
    • @noone - 那是哪个 jvm?
    【解决方案2】:

    BigDecimal 不是最终的,所以你绝对可以自己扩展它,并改变它的行为(尤其是通过覆盖 divideXXX() 方法)。

    您不必更改参数等,但请记住更改实际使用的对象的类型!所以你将使用“你的”方法。

    至于compareTo()等你也不会有任何问题——BigDecimal本身实现了Comparable接口,并有自己的compareTo()

    【讨论】:

    • 你有点误解了我的问题。我知道我可以扩展它,但如果可以的话,我想避免这种情况。并且可能存在默认的compareTo 方法,但我希望它忽略一个小的差异。例如 0 = 0.0001。
    • @noone 我不明白你为什么要避免(?)它。是什么原因,为什么不呢?如果我误解了您的问题,请再解释一下,因为您现在拥有的是解决问题的方法,您拒绝使用它,因为......我真的不知道为什么。
    • 因为我们有很多已经使用 BigDecimal 的代码,所以我必须用 CustomBigDecimal 替换所有这些,这需要更多的工作,并且代码的新开发人员/维护人员可能会忘记使用自定义代码并在使用标准时引入“错误”。它也不会影响 3rd 方库。
    • @noone 好的,那么你打算如何在不改变类型的情况下神奇地改变它?显然你必须改变它,你读过我的回答吗?您不会更改任何方法声明,只会更改运行时使用的对象。根据 IS-A 关系,YourNewBigDecimal 也将是 BigDecimal
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多