我有一个Parent.class(User和Element可以被任何类替换)
public abstract class Parent {
User user;
public void InitUser() {
Fileds f = this.getClass().getDeclaredFields();
for(int i=0; i<f.length; i++) {
f[i].set(this, new Element(i));
}
}
}
Child.class
public class Child extends Parent {
Element e1;
Element e2;
public Child(User user) {
super();
this.user = user;
}
public void doSomethingUsingE1AndE2() {
// do something by using e1 and e2, invoking user's methods.
user.perform(e1);
user.perform(e2);
}
}
在我的Client.class中,下面两种构造和使用Child的方法有什么不同吗?
1。
public class Client() {
User user = new User();
Class childClass = Class.forName("com.xxx.Child");
Constructor con = childClass .getConstructor(User.class);
Object o = con.newInstance(user);
Method initMethod = child.getSuperclass().getDeclaredMethod(
"InitUser");
initMethod.invoke(o);
Method keyMethod = child.getMethod("doSomethingUsingE1AndE2");
keyMethod.invoke(o);
}
2。
public class Client() {
User user = new User();
Child c = new Child(user);
c.InitUser();
c.doSomethingUsingE1AndE2();
}
在创作上没有区别。一个是标准方式(new),另一个是Reflection
。
但是要记住
反射功能强大,但不应任意使用。如果可以在不使用反射的情况下执行操作,那么最好避免使用反射。当通过反射访问代码时,应牢记以下注意事项:
- 性能开销
安全限制
内部器件暴露
总是尝试使用new的方式,除非你没有其他选择。Reflection
从行为上讲,这是相同的-对于两种方法,您将有一个类的实例,并且您将调用一些实例方法。
然而,区别在于编译器的使用。当你反思性地创建一个类的实例,并反思性地调用这个实例上的一些方法时,编译器不会验证你所做的是正确的。避免编译器的帮助,你可能会在运行时出现不同的错误,如NoSuchMethodError
(当你想调用的方法不存在或不能调用时抛出),InvocationTargetException
和ReflectiveOperationException
的其他子类。
遵循非反射方法,更安全-编译器可以验证您尝试做的是正确的(方法是否可访问,参数是否有效,等等),并在程序启动之前将编译器错误返回给您。
注意反射有时是非常有用的,但是
…如果可以在不使用反射的情况下执行操作,那么最好避免使用反射。