我一直在研究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());
我发现这有点违反直觉,因为该方法是在创建实例之前调用的。
反射当然可以用来命名游戏关卡,特别是当有数百个关卡时。
EDIT - SOME SOLUTIONS:
下面是一个在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;
}
}
我发现这有点违反直觉,因为该方法是在创建实例之前调用的
对不起,我不这么认为。在传递给"invoke"之前,首先对方法参数进行评估,因此最终将Foo类的"新"实例传递给method类的"invoke"方法。此外,如果您想知道为什么在方法对象上调用"invoke",这是因为对于给定的类,您只创建一次Method
对象,并且所有后续调用都宁愿依赖于对象的"状态",而不是被调用的"方法"。
here
foo.hello();
不能工作,foo只是一个没有方法hello()的对象。
不熟悉的事物可能看起来违反直觉,但最终新的习惯用语会变得自然。用标准的方法就可以了。要理解它,请考虑方法定义不是对象的一部分,您为类编写一次方法,它独立于任何给定的对象而"存在"。因此,类很有理由说"嘿,方法,把你自己应用到这个对象的上下文中,他是我们中的一员"
我不太清楚你的意思,但这有帮助吗?
Class<?> cls = Class.forName("Foo");
Method method = cls.getMethod("hello");
Object instance = cls.newInstance();
method.invoke(instance);
您没有首先调用该方法。您只是定义了方法,然后调用它。而且,CLS的实例是在我们实际输入invoke之前创建的。我发现反射在java中是一个非常有用的API,它被几乎所有在java上工作的框架(如struts, log4j等)使用。在反射中,你总是定义你想要调用的方法,然后才在你想要操作的实际对象上工作。
希望这对你有帮助!