NosuchMethodException, когда я пытаюсь создать объект, используя reflexion [duplicate]

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

См. « Исключение NullReferenceException при проверке пользовательского AuthorizationAttribute » для несколько подробного примера.

41
задан Steve 13 October 2010 в 16:56
поделиться

5 ответов

Используйте Integer.TYPE вместо Integer.class.

В соответствии с Javadocs это «экземпляр класса, представляющий примитивный тип int».

Вы также можете использовать int.class. Это ярлык для Integer.TYPE. Не только классы, даже для примитивных типов, вы можете сказать type.class в Java.

125
ответ дан Matheus Avellar 25 August 2018 в 20:15
поделиться

Поскольку примитивные типы являются автобоксами, вызов getConstructor(java.lang.Class<?>... parameterTypes) завершится с ошибкой. Вам нужно будет вручную прокрутить доступные конструкторы. Если все типы совпадают, вы в порядке. Если некоторые типы не совпадают, но требуемый тип является примитивным И доступным типом является соответствующий класс-оболочка, тогда вы можете использовать этот конструктор. См. Ниже:

static <C> Constructor<C> getAppropriateConstructor(Class<C> c, Object[] initArgs){
    if(initArgs == null)
        initArgs = new Object[0];
    for(Constructor con : c.getDeclaredConstructors()){
        Class[] types = con.getParameterTypes();
        if(types.length!=initArgs.length)
            continue;
        boolean match = true;
        for(int i = 0; i < types.length; i++){
            Class need = types[i], got = initArgs[i].getClass();
            if(!need.isAssignableFrom(got)){
                if(need.isPrimitive()){
                    match = (int.class.equals(need) && Integer.class.equals(got))
                    || (long.class.equals(need) && Long.class.equals(got))
                    || (char.class.equals(need) && Character.class.equals(got))
                    || (short.class.equals(need) && Short.class.equals(got))
                    || (boolean.class.equals(need) && Boolean.class.equals(got))
                    || (byte.class.equals(need) && Byte.class.equals(got));
                }else{
                    match = false;
                }
            }
            if(!match)
                break;
        }
        if(match)
            return con;
    }
    throw new IllegalArgumentException("Cannot find an appropriate constructor for class " + c + " and arguments " + Arrays.toString(initArgs));
}
5
ответ дан Jake 25 August 2018 в 20:15
поделиться

Если значение примитива int автобоксировано в объект Integer, оно больше не является примитивным. Вы не можете указать из экземпляра Integer, было ли это int в какой-то момент.

Я бы предложил передать два массива в метод test: один с типами и другой со значениями. Он также устранит двусмысленность, если у вас есть конструктор MyClass(Object) и значение строки передачи (getConstructor будет искать конструктор String). Кроме того, вы не можете определить ожидаемый тип параметра, если значение параметра равно null.

2
ответ дан Nikita Rybak 25 August 2018 в 20:15
поделиться

Для ссылки на примитивные типы используйте, например:

Integer.TYPE;

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

object.getClass().isPrimitive()
18
ответ дан Plaudit Design 25 August 2018 в 20:15
поделиться

вы можете написать

int[].class.getComponentType()

или

Integer.TYPE

или

int.class
3
ответ дан user3896501 25 August 2018 в 20:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: