我有两个班级Event1
和Event2
。在运行时,我想使用java反射创建Event1
或Event2
的实例,并将其作为参数传递给另一个函数。该函数是一个多态函数,它根据输入参数类型调用相应的函数。
由于我不知道我可能需要在运行时创建什么类型的子事件实例,因此我将来自'事件'类并创建父类实例。我的问题是,我可以通过'事件' class作为参数,将在运行时解析为多态函数的子类之一。
这是我的代码。
public void myFunc(){
String qualifiedName = new String("events.Event1"); // Event1 info is actually obtained at runtime.
Class cls = Class.forName(qualifiedName);
Event baseEvent = (Event) cls.getDeclaredConstructor().newInstance();
// I want to create an instance like, Event ev1 = new Event1(); and pass it as a parameter.
observer.update(baseEvent); // I get compile time error because no update method takes `Event` class instance as parameter.
}
包含多态函数的Observer类。
public void update(Event1);
public void update(Event2);
Java泛型可以帮助吗?感谢。
答案 0 :(得分:3)
试试这个:
Method method = observer.getClass().getDeclaredMethod("update", baseEvent.getClass());
method.invoke(observer, baseEvent);
答案 1 :(得分:0)
首先是一些术语:如果你在同一个类/接口中有一个同名但方法不同的方法,就像这样:
public void update(Event1 e);
public void update(Event2 e);
它被称为重载,而不是多态。 (很高兴知道你是否想在这个主题上搜索一些东西)。
第二,回答你的问题:没有.Java多态性对此意味着什么。如果你这样调用以前的更新方法:
Event e = //get Event from anywhere
update(e);
编译器将无法决定要调用的update()
的重载版本,因为Java多态不会对重载方法起作用。
您可以尝试将其投射以查看它实际上是什么类型:
try {
update((Event1) e);
} catch(ClassCastException ex) {
//do nothing
}
try {
update((Event2) e);
} catch(ClassCastException ex) {
//do nothing
}
如果e
实际上是Event1
或Event2
,则会调用正确的方法。但是这需要在编译时知道Event
的所有子类(除非你想弄脏并使用反射)。
答案 2 :(得分:0)
顺便说一句..我更喜欢这种方法(避免反思):
Map<Class<? extends Event>,Runnable> actionMapper= new HashMap<Class<? extends Event>, Runnable>();
actionMapper.put(Event1.class, new Runnable() {
@Override
public void run() {
System.out.println("Execution for event 1");
}
});
actionMapper.put(Event2.class, new Runnable() {
@Override
public void run() {
System.out.println("Execution for event 2");
}
});
Event event= new Event1();
Runnable action = actionMapper.get(event.getClass());
action.run();