【问题标题】:Which problems do I have to expect when using Reflection to interface with java.math.BigInteger?使用 Reflection 与 java.math.BigInteger 交互时,我会遇到哪些问题?
【发布时间】:2012-04-20 17:41:09
【问题描述】:

我正在实现一个更快的BigInt 实现,但我不确定在提供与底层平台的互操作方面应该走多远。

今天BigInt 只是包装了一个BigInteger 并且值bigInteger 只是返回了包装的值:

class BigInt(val bigInteger: BigInteger) ...

因为我没有包装 Java 类型,所以我必须做类似的事情

final class BigInt private(final val signum: Int,
                           final private[math] val arr: Array[Int])
  def bigInteger: java.math.BigInteger = {
    // Avoid copying of potentially large arrays.
    val ctor = classOf[java.math.BigInteger]
                 .getDeclaredConstructor(classOf[Array[Int]], classOf[Int])
    ctor setAccessible true
    ctor.newInstance(arr, signum.asInstanceOf[Object])
  }
...
}

这会造成麻烦还是有更好的方法?

【问题讨论】:

  • 我不知道这个数字有多大,但是复制一个小整数数组可能比使用反射更快...
  • 是的,当然。小数组没关系,但数字的大小仅受 RAM 限制。在将数据从不可变数据结构移动到另一个数据结构时,我只是不想占用内存。
  • 整个宇宙的原子数一般估计为10^80。只有 9*32 位,您可以为每个位分配唯一索引。我坚信,如果您需要一个比这更大的自然数,那可能是一个错误或设计错误......

标签: java scala math reflection biginteger


【解决方案1】:

一般来说,当我看到人们使用这样的私有(或其他未记录的)构造函数或方法时,他们会捕获 NoSuchMethodException 并提供替代方案:

object BigInt {
  import java.math.BigInteger

  private val toBigInteger: (Array[Int], Int) => BigInteger = try {
    val ctor = classOf[BigInteger].getDeclaredConstructor(
      classOf[Array[Int]], classOf[Int]
    )
    ctor.setAccessible(true)

    (arr, signum) => ctor.newInstance(arr, signum.asInstanceOf[Object])
  } catch { case _: NoSuchMethodException =>
    (arr, signum) =>
      val buffer = java.nio.ByteBuffer.allocate(arr.length * 4)
      buffer.asIntBuffer.put(arr)
      new BigInteger(signum, buffer.array)
  }
}

final class BigInt(final val signum: Int, final val arr: Array[Int]) {
  def bigInteger = BigInt.toBigInteger(arr, signum)
}

我还把反射业务移到了一个伴随对象上,以避免每次打电话给bigInteger 时都要支付大部分费用。

【讨论】:

  • 难道我不需要注意SecurityException 而不是NoSuchMethodException 吗?有趣的是,JavaDoc 甚至提到这个构造函数是公开的,所以我认为它永远不会消失。
猜你喜欢
  • 2017-07-26
  • 1970-01-01
  • 2016-03-18
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多