简体   繁体   English

使用反射与 java.math.BigInteger 交互时,我会遇到哪些问题?

[英]Which problems do I have to expect when using Reflection to interface with java.math.BigInteger?

I'm implementing a faster BigInt implementation and I'm not sure on how far I should go to provide interop with the underlying platform.我正在实施一个更快的BigInt实施,但我不确定我应该 go 在多大程度上提供与底层平台的互操作。

Today BigInt just wraps a BigInteger and the value bigInteger just returns the wrapped value:现在BigInt只是包装了一个BigInteger ,值bigInteger只是返回了包装后的值:

class BigInt(val bigInteger: BigInteger) ...

Because I'm not wrapping a Java type, I would have to do something like因为我没有包装 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])
  }
...
}

Can this cause trouble or is there a better way to do it?这会造成麻烦还是有更好的方法来做到这一点?

In general when I've seen people use private (or otherwise undocumented) constructors or methods like this, they catch NoSuchMethodException and provide an alternative:一般来说,当我看到人们使用私有(或其他未记录的)构造函数或方法时,他们会捕获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)
}

I've also moved the reflection business off to a companion object in order to avoid paying for most of it every time you call bigInteger .我还将反射业务移到了同伴 object 上,以避免每次调用bigInteger时都需要支付大部分费用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM