Ответ 1
Есть ли у них какая-то особая причина, по которой вы не можете использовать отражение, чтобы получить доступ к классу?
Я смог сделать это без каких-либо проблем, вот код:
public static void main(String[] args) throws Exception {
Constructor<?> constructor = Class.forName("java.math.MutableBigInteger").getDeclaredConstructor(int.class);
constructor.setAccessible(true);
Object x = constructor.newInstance(new Integer(17));
Object y = constructor.newInstance(new Integer(19));
Constructor<?> constructor2 = Class.forName("java.math.MutableBigInteger").getDeclaredConstructor(x.getClass());
constructor2.setAccessible(true);
Object z = constructor.newInstance(new Integer(0));
Object w = constructor.newInstance(new Integer(0));
Method m = x.getClass().getDeclaredMethod("multiply", new Class[] { x.getClass(), x.getClass()});
Method m2 = x.getClass().getDeclaredMethod("mul", new Class[] { int.class, x.getClass()});
m.setAccessible(true);
m2.setAccessible(true);
// Slightly faster than BigInteger
for (int i = 0; i < 200000; i++) {
m.invoke(x, y, z);
w = z;
z = x;
x = w;
}
// Significantly faster than BigInteger and the above loop
for (int i = 0; i < 200000; i++) {
m2.invoke(x, 19, x);
}
BigInteger n17 = new BigInteger("17");
BigInteger n19 = new BigInteger("19");
BigInteger bigX = n17;
// Slowest
for (int i = 0; i < 200000; i++) {
bigX = bigX.multiply(n19);
}
}
Изменить: Я решил поиграть немного больше, похоже, что java.math.MutableBigInteger не ведет себя так, как вы ожидали.
Он работает по-разному, когда вы размножаетесь, и он генерирует прекрасное исключение, когда ему приходится увеличивать размер внутреннего массива при назначении самому себе. Я думаю, что я ожидаю. Вместо этого я должен обмениваться объектами так, чтобы он всегда помещал результат в другой MutableBigInteger. После нескольких тысяч вычислений накладные расходы от отражения становятся незначительными. MutableBigInteger в конечном итоге продвигается вперед и предлагает более высокую производительность по мере увеличения количества операций. Если вы используете функцию "mul" с целочисленным примитивом в качестве значения для умножения, MutableBigInteger работает почти в 10 раз быстрее, чем с помощью BigInteger. Я думаю, это действительно сводится к тому, с чем вам нужно умножаться. В любом случае, если вы запустили этот расчет "100 миллиардов раз", используя рефлексию с MutableBigInteger, он будет работать быстрее, чем BigInteger, потому что будет "меньше" распределения памяти, и он будет кэшировать отражающие операции, удаляя служебные данные из отражения.