Java Вопрос, как получить значение метода из неизвестного объекта

У меня есть много объектов, определенных в системе, возможно, 1000 объектов, и у некоторых из них есть этот метод:

public Date getDate();

В любом случае я могу сделать что-то вроде этого:

Object o = getFromSomeWhere.....;

Method m = o.getMethod("getDate");
Date date = (Date) m.getValue();

person jojo    schedule 28.04.2009    source источник
comment
Есть ли интерфейс, реализуемый этими объектами для получения метода getDate()?   -  person jjnguy    schedule 28.04.2009
comment
Если есть интерфейс, то просто без использования отражения вы можете использовать оператор instanceof перед приведением к этому интерфейсу.   -  person Azder    schedule 28.04.2009
comment
нет интерфейса или того же родительского класса, поэтому я должен делать отражение....   -  person jojo    schedule 28.04.2009
comment
Потому что, если нет единого типа, который определяет метод и в который вы можете привести все объекты, отражение — единственный способ получить дескриптор метода.   -  person Rytmis    schedule 28.04.2009


Ответы (5)


Если вы можете заставить их все реализовывать интерфейс, это, безусловно, будет лучшим вариантом. Однако отражение также будет работать, и ваш код почти готов:

Object o = getFromSomeWhere.....;
Method m = o.getClass().getMethod("getDate");
Date date = (Date) m.invoke(o);

(Правда, есть куча исключений, которые вам нужно обработать...)

Для полного примера:

import java.lang.reflect.*;
import java.util.*;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        Object o = new Test();
        Method m = o.getClass().getMethod("getDate");
        Date date = (Date) m.invoke(o);
        System.out.println(date);
    }

    public Date getDate()
    {
        return new Date();
    }
}
person Jon Skeet    schedule 28.04.2009
comment
Tsk tsk, бросает Exception - плохой тон. - person Henrik Paul; 28.04.2009
comment
@Henrik: Что касается производственного кода, я вполне согласен. Но при написании примера приложения для демонстрации определенного фрагмента кода (на самом деле важны только три строки) я думаю, что это нормально. Я упоминаю в посте, что есть куча исключений для обработки. Будет ли полезно явно указывать их в тестовом приложении? Действительно ли загромождение программы сделает что-нибудь яснее? Где выгода? - person Jon Skeet; 28.04.2009
comment
Вы правы, действительно. Я, должно быть, пропустил упоминание об исключениях в моей утренней спешке, мои извинения. - person Henrik Paul; 28.04.2009
comment
Я отчасти согласен, к сожалению, люди копируют стиль кода минимально воспроизводимого примера, который они видели. - person Tom Hawtin - tackline; 28.04.2009

Попробуй это:

Object aDate = new Date();
Method aMethod = aDate.getClass().getMethod("getDate", (Class<Void>[]) null);
Object aResult = aMethod.invoke(aDate, (Void) null);

Вы должны добавить try-catch, чтобы определить, действительно ли существует метод getDate перед вызовом.

person Azder    schedule 28.04.2009

Если есть интерфейс, требующий метода getDate(), вы можете проверить его, используя следующий код:

if (o instance of GetDateInterface){
    GetDateInterface foo = (GetDateInterface) o;
    Date d = foo.getDate();
}
person jjnguy    schedule 28.04.2009

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

import java.util.Date;

interface Dated {
  public Date getDate();
  public void setDate(Date date);
}

class FooObject implements Dated {
  private Date date;
  public void setDate(Date date) { this.date = date; }
  public Date getDate() { return date; }
  // other code...
}

public static void main (String[] args) {
  Object o = getRandomObject(); // implemented elsewhere
  if (o instanceof Dated) {
    Date date = ((Dated)o).getDate();
    doStuffWith(date);
  }
}
person Henrik Paul    schedule 28.04.2009
comment
я не могу изменить другой код ... хм ... иначе ... тогда я сделаю так ... спасибо в любом случае - person jojo; 28.04.2009

Если вы не возражаете против дополнительной зависимости, BeanUtils может сделать это за вас.

person sproketboy    schedule 28.04.2009