我一直在研究Java反思。这是维基百科http://en.wikipedia.org/wiki/Reflection_(computer_programming)的一个例子:
// Without reflection
new Foo().hello();
// With reflection
Class<?> cls = Class.forName("Foo");
cls.getMethod("hello").invoke(cls.newInstance());
我发现这有点违反直觉,因为在创建实例之前会调用该方法。
当然,反思可以用来调用游戏等级,特别是如果它们有数百个。
编辑 - 一些解决方案:
以下是一个适用于Android的反射的简单示例:
try {
Class<?> clazz = Class.forName("com.test.Foo");
clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateException(e);
}
和类文件
public class Foo {
Foo(){
hello();
}
private void hello() {
Log.e("FOO", "Hello!");
}
}
假设有人想通过反思调用一个Activity:
Activity activity;
try {
Class<?> clazz = Class.forName("com.test.MyLevelActivity");
activity = (Activity) clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateException(e);
}
startActivity(new Intent(this,activity.getClass()));
假设应该通过反射“加载”包含数据和方法的级别:
Level currentLevel;
try {
Class<?> clazz = Class.forName("com.test.Level_1_1");
currentLevel = (Level) clazz.newInstance();
} catch (Exception e) {
throw new IllegalStateException(e);
}
String levelName = currentLevel.getLevelName();
String result = Integer.toString(currentLevel.processData(3, 7));
Toast.makeText(this, levelName + " result= " + result, Toast.LENGTH_LONG).show();
以下是课程:
public abstract class Level {
public abstract String getLevelName();
public abstract int processData(int a, int b);
}
public class Level_1_1 extends Level{
private String levelName = "level 1.1";
public String getLevelName(){
return levelName;
}
public int processData(int a, int b) {
return a * b;
}
}
答案 0 :(得分:7)
我发现这有点违反直觉,因为在创建实例
之前调用该方法
抱歉,不要这么认为。方法参数在传递给“invoke”之前首先被评估,因此最终将Foo类的“new”实例传递给Method类的“invoke”方法。另外,如果你想知道为什么在方法对象上调用“invoke”,那是因为对于给定的类,你只创建Method
个对象一次,所有后续的调用都依赖于它的“状态”。对象而不是被调用的“方法”。
答案 1 :(得分:3)
这里
foo.hello();
无法正常工作,foo只是一个没有方法hello()的对象。
不熟悉的事情可能看似违反直觉,但最终新的习语变得自然。只需采用标准方法。
要理解它,请考虑方法定义不是对象的一部分,为类创建一次方法,它“独立于任何给定对象”。因此,对于班级说“嘿方法,在这个对象的背景下应用自己,他是我们中的一员”是非常合理的
答案 2 :(得分:2)
你的意思并不是很清楚,但这有帮助吗?
Class<?> cls = Class.forName("Foo");
Method method = cls.getMethod("hello");
Object instance = cls.newInstance();
method.invoke(instance);
答案 3 :(得分:1)
你没有先调用这个方法。你只是定义方法,然后调用它。另外,cls的实例是在我们实际进入invoke之前创建的。我发现反射在java中是一个非常有用的API,几乎所有在java上使用的framworks都使用它,如struts,log4j等。在反射中,你总是定义你想要调用的方法,然后才能处理实际的对象你想经营。
希望这有帮助!