2015-04-07 2 views
4

Я буду держать его кратким, у меня есть Dog класс вроде следующего:Отражение - Получение различные результаты HashMap - LinkedHashMap

public class Dog 
{ 
    public void Foo() 
    { 
     System.out.println("Right Call"); 
    } 

    public void Boo() 
    { 
    System.out.println("Wrong Call"); 
    } 
} 

и основной метод, как следующие:

HashMap<String, Method> map = new HashMap<String, Method>(); 

Dog d = new Dog(); 

Method[] method = d.getClass().getMethods(); 

map.put("foo", method[0]); 

Method a = map.get("foo"); 

try { 
    a.invoke(d, null); 
} catch (IllegalAccessException | IllegalArgumentException 
     | InvocationTargetException e) { 
    e.printStackTrace(); 
} 

Всякий раз Я запускаю его снова, он просто произвольно дает Right Call или Wrong Call выхода.

Я должен быть уверен, что каждый раз, когда я помещаю ключ "foo", он должен быть вызван методом Foo(), а не Boo().

По-видимому, это не облегчает мою проблему с «вызовом метода». Как я могу решить эту проблему? Я должен каждый раз называть правильный метод. Я совершенно новичок в этом размышлении, есть ли что-то, что я не должен делать, или что-то, что я делаю неправильно? Или есть лучший способ реализовать этот метод?

EDIT: Я также пробовал LinkedHashMap, однако результат тот же.

спасибо.

+1

Это не имеет ничего общего с HashMap. Используйте http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getDeclaredMethod%28java.lang.String,%20java.lang.Class...%29, чтобы получить метод вы действительно хотите вместо [0]. –

ответ

8

Из Javadoc из Class.getMethods():

Элементы в массиве, возвращаемом не сортируются и не в определенном порядке.

Однако, ваш код предполагает, что элемент с индексом 0 является методом Foo(). Не делайте этого предположения. Найдите метод, который имеет имя Foo.

Это говорит о том, что отражение, вероятно, не подходит для работы, которую вы пытаетесь сделать. Вы должны объяснить на более высоком уровне то, что вы пытаетесь сделать, и почему вы думаете, что использование рефлексии - хорошая идея. Обычно это не так.

3

Результат getMethods() не сортируется, поэтому нет гарантий, что method[0] является Foo() (не Boo()). Вам нужно проверить его перед тем, как поставить карту в качестве значения для клавиши «foo».

5

Это не имеет ничего общего с введением методы в карте, насколько я могу сказать - вы можете удалить карту часть целиком и по-прежнему сталкиваетесь с тем же вопросом:

Dog d = new Dog(); 

Method methods = d.getClass().getMethods();   
Method a = methods[0]; 

try { 
    a.invoke(d, null); 
} catch (IllegalAccessException | IllegalArgumentException 
     | InvocationTargetException e) { 
    e.printStackTrace(); 
} 

Фундаментально, вы видя, что getMethods() не возвращает методы из класса в том порядке, на который вы должны положиться. Если вы хотите специально вызвать свой метод Foo (который должен быть foo, чтобы следовать соглашениям об именовании Java), вы, вероятно, должны использовать Class.getMethod("foo"), чтобы получить метод по имени.

1

Вы могли бы с курса также использовать следующее соображение:

Dog d = new Dog(); 
map.put("foo", d.getClass().getMethod("Foo"); 
Method m = map.get("foo"); 
m.invoke() 

Этот код явно недостающий все попробовать поймать и некоторые другие вещи, но это покажет вам важный бит. Вы никогда не должны полагаться на порядок в getMethods(). Вместо этого, если вы знаете, какой метод вызывается, всегда используйте вызов getMethod, чтобы получить его по имени.Таким образом, вы обязательно получите правильный метод.

1

Я думаю, что Карта вызвала небольшую красную селедку.

Dog d = new Dog(); 
    try { 
     d.getClass.getMethod("Foo").invoke(d, null); 
    } catch (IllegalAccessException | IllegalArgumentException 
      | InvocationTargetException | NoSuchMethodException e) { 
     e.printStackTrace(); 
    } 

Не сто процентов уверен в этом, но я считаю, что вы также должны поймать NoSuchMethodException.

Скажу, если вы просто не пытаетесь узнать об отражении api, я бы подумал дважды, прежде чем использовать отражение. В большинстве случаев это не правильный инструмент для работы.