2017-01-22 3 views
0

Я пытаюсь написать собственную реализацию теста примитивности Миллера Рабина. Я мог бы заставить его работать, но он был очень медленным для значений размером более 64 бит.Необработанное исключение: NoSuchMethodException

В проекте стандарта ANSI X9.80, «ОБРАЗОВАНИЕ ПРАЙМ-НОМЕРОВ, ИСПЫТАНИЕ ПРЯМОЙ И СЕРТИФИКАТОВ ПРИМ.», Они определяют поведение до 1024 бит. Моя программа (на i7 6700k) займет в лучшем случае месяцы в лучшем случае для работы с одним 1024 битным целым числом.

Итак, я обратился к реализации Java-теста Миллера Рабина, чтобы узнать, какие микро-оптимизации они использовали для обеспечения производительности.

Я проработал свой исходный код, но я подбежал к стене. Многие методы, которые они используют, являются частными, а тестирование поведения ваших кодов по сравнению с кодом, который вы не можете выполнить, довольно сложно. Для начала первый внутренний метод, который я хотел назвать, - BigInteger.mod2(int)

Я не запрограммировал широко в Java раньше, но вот где я застрял:

import java.lang.reflect.*; 
import java.math.BigInteger; 

public class HelloWorld 
{ 
    public static void main(String[] args) 
    { 
     BigInteger a = new BigInteger("123456789101112"); 
     Method mod2 = BigInteger.class.getDeclaredMethod("mod2", int.class); 
     //Class[] arg_types = new Class[1]; 
     //arg_types[0] = int.class; 
     //Method mod2 = BigInteger.class.getDeclaredMethod("mod2", arg_types); 
     mod2.setAccessible(true); 
     Object b = mod2.invoke(a, 32); 
     System.out.print(b); 
    } 
} 

Обе версии исключений NoSuchMethodException вызов бросить «getDeclaredMethod». Я просмотрел документацию для «getDeclaredMethod», и они говорят, что делают именно то, что я сейчас делаю, когда люди спрашивают, как заставить эту функцию работать.

Любые советы о том, как использовать частные методы BigInteger, в частности BigInteger.mod2(int), были бы очень благодарны. Благодаря!

+1

Как-то я думаю, вы пропустили всю точку зрения [частный] (https: //en.oxforddictionaries.com/definition/private). –

+0

Каким образом? Я пытаюсь написать собственную реализацию частного метода в классе java. Я хотел бы иметь возможность напрямую вызвать этот метод, чтобы сравнить вывод моего кода и частного метода. –

+1

Не только это, но любые оптимизации, которые вы можете сделать, используя частные методы в таких местах, как 'BigDecimal', будут три раза сбрасываться путем использования рефлексии. –

ответ

1

Вы на правильном пути. Единственный способ вызвать частные методы в Java - использовать API отражения. Вы уже используете его. Единственная ошибка в вашей программе заключается в том, что вы не обрабатываете проверенное исключение. Просто объедините вызовы вызова вызова и метода getDeclaredMethod с помощью try-catch, и вам хорошо идти.

BigInteger a = new BigInteger("123456789101112"); 
    Method mod2 = null; 
    try { 
     mod2 = BigInteger.class.getDeclaredMethod("mod2", int.class); 
    } catch (NoSuchMethodException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (SecurityException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    //Class[] arg_types = new Class[1]; 
    //arg_types[0] = int.class; 
    //Method mod2 = BigInteger.class.getDeclaredMethod("mod2", arg_types); 
    mod2.setAccessible(true); 
    Object b; 
    try { 
     b = mod2.invoke(a, 32); 
      System.out.print(b); 
    } catch (IllegalAccessException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IllegalArgumentException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

прочитать Javadoc для класса метода :: getDeclaredMethod. В нем говорится, что этот метод выдает два исключения (1) NoSuchMethodException и (2) SecurityException.

То же самое, прочитайте Javadoc для метода Method :: invoke. Он говорит, что этот метод исключает три исключения (1) IllegalAccessException (2) IllegalArgumentException (3) InvocationTargetException.

Вызывающий метод этих методов должен улавливать эти исключения или добавлять предложение throws к его собственной подписи метода, перечисляя все эти исключения, что он не обрабатывает.

+0

Я думаю, что это правильный ответ. OP не дает понять, но его код не компилируется, поэтому его фактическая проблема может быть ошибкой компиляции «необработанного исключения», и это исправит это. – EJP

+0

Или добавьте 'throws Exception' в ваш' main' метод. Если это для изучения, нет никакого вреда в этом. Для реального приложения, избегайте этого! –

+0

@ OlivierGrégoire да, этот вариант всегда есть. Я уже упоминал об этом в последней строке моего ответа. Может быть, мне нужно подчеркнуть это. Вместо того, чтобы ловить эти отдельные исключения, OP может просто добавить 'throws' в свой' main' метод. Однако я не буду рекомендовать это кому-то, кто пытается правильно изучить Java. Как только он устраивает обработку исключений, он может использовать 'throws' для быстрого тестирования. – VHS

0

В вашем примере вы не смогли обработать проверенные исключения, которые могут быть вызваны getDeclaredMethod. Изменить подпись на

public static void main(String[] args) throws Exception { 

После этого ваш код должен работать. Если getDeclaredMethod все еще поднимает NoSuchMethodException, то действительно нет метода mod2 в BigInteger, с которым вы связываетесь.

Это произойдет, если вы используете JDK с BigInteger, который не имеет метода с подписью private mod2(int). Например, путь класса Gnu не имеет.

+0

Хотел бы я правильно отметить оба ответа. Я в основном новичок в java, был мужчиной C/C++ годами ... Не понял дополнительных требований за исключениями. Другой парень ответил сначала, хотя, я думаю, он получает галочку –

+0

Да, несколько дней, я бы хотел, чтобы я был еще парнем C. Хорошая среда IDE будет принимать большую часть боли из Java, если вам нужно ее использовать. Есть много бесплатных. Сообщество сообщества intellij, вероятно, является самым популярным. – teppic