我有一个Parent.class(用户和元素可以被任何类替换)
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();
}
非常感谢。
答案 0 :(得分:2)
创作没有区别。一种是标准方式(新),另一种是Reflection
。
但请记住
反思很强大,但不应随意使用。如果可以在不使用反射的情况下执行操作,则优选避免使用它。通过反射访问代码时,应牢记以下问题。
绩效开销
安全限制
内部曝光
除非您没有其他选择,否则请始终尝试使用新方式反思。
答案 1 :(得分:1)
在行为上,它是相同的 - 对于这两种方法,您将拥有一个类的实例,并且您将调用一些实例方法。
然而,区别在于编译器的 use 。
当你反思性地创建一个类的实例,并在这个实例上反射性地调用某个方法时,编译器不会验证你所做的是正确的。避免编译器的帮助,您最终可能会在运行时遇到不同的错误,例如NoSuchMethodError
(当您希望调用的方法不存在或无法调用时抛出),{{1} }和ReflectiveOperationException
的其他子类。
遵循非反射方法,更安全 - 编译器可以验证您尝试执行的操作是否正确(方法是否可访问,参数是否有效等)并且会在之前抛出编译器错误该计划已经启动。
请注意,反射有时非常有用,但
...如果可以不使用反射执行操作,则最好避免使用它。