先自定义一对父类与子类
public class A_For_Reflect_Instance_and_Polymorphism { private int my_field=0; public void my_method(){ System.out.println("这是A的方法"); } }
public class AA_For_Reflect_Instance_and_Polymorphism extends A_For_Reflect_Instance_and_Polymorphism { public void my_method(){ System.out.println("这是AA的方法"); } public void not_in_A_method(){ System.out.println("这是AA的方法.A中没有这个方法"); } }
A_For_Reflect_Instance_and_Polymorphism 以下简称A。
AA_For_Reflect_Instance_and_Polymorphism以下简称AA。
对于多态的普通展示一般有:
A a=new AA();//a的编译时为A。a的运行运行时为AA。a只能使用A中的方法。但实际使用却是AA中继承与重写的方法。 a.my_method();//调用AA中的方法。 a.not_in_A_method();//无法通过编译。
以上理所当然。
我的疑问来自看到有些人用反射时是这样的。
Class c_a=Class.forName("A"); A a=(A)c_a.newInstance();
使用强转来确定a对象。这让我很不爽。因为我觉得这样强转就失去了Java反射的动态意义了。
于是乎就想直接用Object自然的接收newInstance()方法所返回的Object对象。
Class c_a=Class.forName("A"); Object obj=obj.newInstance();
但是这样会不会受到编译时类是Object的限制。导致我非Object的方法便不能用了?
如果这样
obj.my_method();
确实无法使用。编译无法通过。
但是使用反射。便可以调用。
Method method1=c_a.getMethod("my_method"); method1.invoke(obj);
这样利用Java反射实现动态语言的一些特性便可以实现。只是这代码写起来实在是太冗长了。
另外需要说明一下,方法getClass()所得到的是对象运行时类的Class。
Object obj=new A(); System.out.println(obj.getClass()); //所得到的结果为 // class A
下面是我实验中的执行代码。
import java.lang.reflect.Method; public class Reflect_Instance_and_Polymorphism { public static void main(String[] args) throws Exception { //普通多态 A_For_Reflect_Instance_and_Polymorphism a_obj=new AA_For_Reflect_Instance_and_Polymorphism(); a_obj.my_method(); System.out.println(); //反射多态 测试 Class c=a_obj.getClass(); System.out.println("obj.getClass返回的类为"+c+"此为运行时类"); Object obj=c.newInstance();//实例化 try{ //obj.my_method(); }catch(Exception e){ }finally{ System.out.println("obj在编译时是Object的。obj无法调用my_method。"); } System.out.println(); System.out.println("用反射调用对象的方法"); Method method1=c.getMethod("my_method"); method1.invoke(obj); System.out.println("用反射即调用运行时方法"); Method method2=c.getMethod("not_in_A_method"); method2.invoke(obj); System.out.println("反射调用的方法无视编译时。所调用的方法取决于Class对象所对应的类。"); } }