使用Reflection与java.math.BigInteger接口时,我必须遇到哪些问题?

时间:2012-04-07 13:06:32

标签: java scala math reflection biginteger

我正在实施更快的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])
  }
...
}

这会引起麻烦还是有更好的方法呢?

1 个答案:

答案 0 :(得分:3)

一般情况下,当我看到人们使用私有(或其他未记录的)构造函数或类似方法时,他们会捕获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时支付大部分费用。