62,612
社区成员
发帖
与我相关
我的任务
分享
//利用反射,加载该类进入内存
Class cls=Class.forName("Person");
//利用空参构造创建对象
Object obj=cls.newInstance();
//获取方法对象
Method method=cls.getMethod(methodName);
//执行方法
method.invoke(obj);
System.out.println("——————————————————————————");
Object obj2 = new Parent();
System.out.println(obj2);//com.wdk.fulfill.ReflexDemo$Parent@135fbaa4
obj2.method(); //不可调用
所以我可不可以这样理解,用new生成的实例化对象,在调用实例化的对象的方法的时候,会受到引用的变量的限制,故我的添加内容中,Object类型的obj2不能调用其子类Parent的方法method。而使用反射的话,例如你的obj,它是一个指向了Parent实例对象的变量,当Parent的Class以实例化对象obj来Invoke调用方法method,就不会考虑引用变量的限制了,反射会通过obj直接得到这个实例化的存储于堆的这个Parent对象,然后查找这个method去调用。[/quote]
普通调用
new Parent().method() 调的父类方法
new Child().method() 调的父类方法
那反射其实也一样
其中很多细节的判断是在native方法里面进行的 我这边没有c源码所以猜测一下
Parent.class.getMethod("method").invoke(Child.class.newInstance())的时候 会判断Child.class.newInstance()这个参数是否Parent.class的子类 也就是Parent.class.isAssignableFrom(Child.class) 如果是false 就报错ava.lang.IllegalArgumentException: object is not an instance of declaring class这个异常 如果true再判断 参数是不是Parent类型 是的话就直接用Parent的Method 不是的话就用参数实际类型的Method
System.out.println("——————————————————————————");
Object obj2 = new Parent();
System.out.println(obj2);//com.wdk.fulfill.ReflexDemo$Parent@135fbaa4
obj2.method(); //不可调用
public class ReflexDemo {
static class Parent {
public void method() {
System.out.println("I am Parent");
}
}
static class Child extends Parent {
@Override
public void method() {
System.out.println("I am Child");
}
}
public static void main(String[] args) throws Exception {
Parent.class.getMethod("method").invoke(new Parent());//I am Parent
Parent.class.getMethod("method").invoke(new Child());//I am Child 调的是子类的方法
//反射生成的对象跟new的没有什么区别 用的还是实际类型 如果类型非法会报错
Object obj = Parent.class.newInstance();
System.out.println(obj.getClass().getName()); //com.wdk.fulfill.ReflexDemo$Parent 这个obj的实际类型
Object obj1 = Child.class.newInstance();
System.out.println(obj1.getClass().getName()); //com.wdk.fulfill.ReflexDemo$Child 这个obj1的实际类型
Parent.class.getMethod("method").invoke(obj);//I am Parent
Parent.class.getMethod("method").invoke(obj1);//I am Child 调的是子类的方法
Parent.class.getMethod("method").invoke("1");//java.lang.reflect.InvocationTargetException
}
}
public class ReflexDemo {
static class Parent {
public void method() {
System.out.println("I am Parent");
}
}
static class Child extends Parent {
@Override
public void method() {
System.out.println("I am Child");
}
}
public static void main(String[] args) throws Exception {
Parent.class.getMethod("method").invoke(new Parent());//I am Parent
Parent.class.getMethod("method").invoke(new Child());//I am Child 调的是子类的方法
}
}