Просто чтобы добавить больше к этому ответу и дать вам еще немного подумать над этим (постараюсь сделать это простым, неформальным способом).Использование интерфейсов является правильным способом выполнения такой операции.Однако я хочу остановиться на «плохой идее»:
for (Object o : lists.getList(listNumber)) {
System.out.println(o.getClass().getMethod("getText"));
}
То, что вы здесь делаете, использует механизм под названием Отражение :
Отражение - это особенность языка программирования Java.Это позволяет исполняющей Java-программе исследовать или «анализировать» себя и манипулировать внутренними свойствами программы.Например, класс Java может получить имена всех своих членов и отобразить их.
То, что вы на самом деле пытались использовать, использует этот механизм для извлечения метода с помощью Class
отраженияэкземпляр объекта вашего класса (звучит странно, не правда ли?).
С этой точки зрения вам нужно подумать, что, если вы хотите вызвать свой метод, у вас теперь есть, в некотором смысле, мета-Класс для управления вашими объектами.Думайте об этом как об объекте, который находится на один шаг выше ваших объектов (аналогично сну во сне, в Начало ).В этом смысле вам нужно извлечь метод, а затем вызвать его другим (мета-подобным) способом:
java.lang.reflect.Method m = o.getClass().getMethod("getText");
m.invoke(o);
Используя эту логику, вы можете перебирать список объектов, проверить, если методсуществует, затем вызовите ваш метод.
Это плохая, ПЛОХАЯ идея.
Почему?Что ж, ответ зависит от самого отражения: отражение напрямую связано с временем выполнения - т.е. когда программа выполняется, практически выполняя все вещи во время выполнения, минуя мир компиляции.
Другими словами, делая это, вы обходите механизм ошибок компиляции Java, позволяя таким ошибкам возникать в runtime .Это может привести к нестабильному поведению программы во время ее выполнения - помимо снижения производительности при использовании Reflection, которое здесь не будет анализироваться.
Примечание: хотя использование отражения потребует использования обработки проверенных исключений, оно по-прежнемуне очень хорошая идея сделать это - поскольку вы практически пытаетесь скрыть плохое решение.
С другой стороны, вы можете следовать механизму наследования Java через классы и интерфейсы - определить интерфейс с помощью вашего метода (давайте назовем это Textable
), убедитесь, что ваши классы реализуют его, а затем используйте его в качестве базового объекта в объявлении списка (@alexrolea реализовал это в своем ответе, как и @OldCurmudgeon).
Таким образом, ваша программа по-прежнему будет принимать решение о вызове метода во время выполнения (с помощью механизма, называемого позднее связывание ), но вы не обойдете механизм ошибок компиляции Java.Подумайте об этом: что произойдет, если вы определите реализацию Textable без предоставления класса - ошибка компиляции!А что если вы поместите нетекстовый объект в список Textable
с?Угадай, что!Снова ошибка компиляции.И этот список можно продолжить ....
В общем, избегайте использования Reflection, когда вы можете это сделать.Отражение полезно в некоторых случаях, когда вам нужно обработать вашу программу таким мета-способом, и нет другого способа сделать такие вещи.Однако это не тот случай.
ОБНОВЛЕНИЕ: Как показывают некоторые ответы, вы можете использовать instanceof
, чтобы проверить, есть ли у вас конкретный экземпляр объекта Class, который содержит ваш метод, а затем вызвать соответственно.Хотя это кажется простым решением, оно плохо с точки зрения масштабирования: что, если у вас есть 1000 различных классов, которые реализуют такой же метод, который вы хотите вызвать?