Which problems do I have to expect when using Reflection to interface with java.math.BigInteger?
biginteger, java, math, reflection, scala
Solution
In general when I've seen people use private (or otherwise undocumented) constructors or methods like this, they catch `NoSuchMethodException` and provide an alternative:
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`.
Problem
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. Today `BigInt` just wraps a `BigInteger` and the value `bigInteger` just returns the wrapped value: ``` class BigInt(val bigInteger: BigInteger) ... ``` Because I'm not wrapping a Java type, I would have to do something like ``` 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?