2013-09-11 5 views
5

Я знаю, что есть много quesitons относительно отражений и примитивных типов, но я действительно не получал точной информации, которую я искал. Моя проблема следующая: Я хочу, чтобы методы (через отражение) были полностью динамическими, это значит, что я хочу их вызывать, даже если я точно не знаю типы параметров.Как узнать, является ли что-то примитивным типом после автобоксинга?

public Object invoke(Object objectContainingMethod,String methodName, Object...params) { 
    Object result = null; 
    int length = params.length; 
    Class<?>[] paramTypes = new Class<?>[length]; 

    for(int i=0; i<length; i++) { 
     paramTypes[i] = params[i].getClass(); 
    } 

    try { 
     Method method = objectContainingMethod.getClass().getMethod(methodName, paramTypes); 
     // not hard coded like getMethod(methodName, String.class, int.class, double.class); 
     result = method.invoke(objectContainingMethod, params); 
    } catch (NoSuchMethodException | SecurityException | 
      IllegalAccessException | IllegalArgumentException | 
      InvocationTargetException e) { 
     e.printStackTrace(); 
    } 

    return result; 
} 

Проблема заключается в том, параметр для метода необходимо преобразовать в объект, но когда я это сделать вы не можете обнаружить (ли что-нибудь еще, так пожалуйста, не ненавидеть ^^ не оптимизированы) больше, если это примитивный тип из-за автоматического бокса. Что происходит, когда я пытаюсь вызвать метод «Шар» из класса Струнных с параметром INT:

String instance = "hello"; 
Object result = invoke(instance,"charAt",0); 

, которые, очевидно, приводит к:

java.lang.NoSuchMethodException: java.lang.String.charAt(java.lang.Integer) 
at java.lang.Class.getMethod(Unknown Source)... 

Он искал Integer вместо int из-за автоматического бокса. Итак, есть ли работа над тем, что я пытаюсь сделать здесь? Я знаю, как обнаружить примитивные типы, но не тогда, когда они автоматически помещаются в коробки для своих типов оберток. Любая помощь приветствуется.

+2

@sara не по пункту по этому вопросу. В примере кода есть дополнительный слой инкапсуляции, который скрывает тип объекта с помощью autoboxing. – Dev

ответ

4

Вам необходимо передать массив класса в качестве аргумента в свой собственный метод invoke, который имеет явные типы для поиска в сигнатуре метода вместо того, чтобы пытаться напрямую определить типы из параметров. Именно поэтому Class.getMethod(String, Class[]) требует типов вместо вывода из параметров.

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

public Object invoke(Object objectContainingMethod,String methodName, Class<?>[] types, Object...params) 
+0

Теперь, когда я смотрю на него, это кажется довольно очевидным, lol. Я думаю, мне просто нужно определить, какие классы следует поместить в массив, когда im обрабатывает каждый параметр (когда я получаю int, я помещаю int.class туда и т. Д.). Спасибо и жаль, что тратили ваше время ^^. – Alastorftw

+1

@Alastorftw Когда вы получаете int, вы будете использовать 'Integer.TYPE' в качестве класса для обозначения примитивного' int' (не int.class, как вы прокомментировали, а не Integer.class). – splungebob

+1

Исправление: 'int.class' будет работать так же, как' Integer.TYPE'. Тем не менее, Integer.class будет по-прежнему терпеть неудачу. – splungebob

Смежные вопросы