Java程序运行分为三个阶段:
1.源代码阶段
该阶段中程序仍是后缀为.java的原始代码,或使用javac命令编译后的后缀为.class的二进制编码文件。
2.类阶段
该阶段常常被忽略,但该阶段完成相当重要的工作。程序在完成第一阶段后,不管是.java还是.class文件,都位于磁盘中,无法直接为需要实例化的类提供直接参考或帮助。此时需要完成的工作是:使用Java定义的class类在系统中存储一个完整类,包含三部分:
(1)内部域(成员变量)
(2)构造器
(3)方法(成员函数)
这三部分分开以数组的方式存在内存中,实例化类后,对成员方法的调用或对成员变量的修改都将通过该数组完成(类似C++保存了函数指针的数组)。
3.运行时阶段
该阶段则借助第二阶段完成的class类完成实例化对象,并通过对象实现一系列操作。
Java提供了一种名为反射的机制,使我们能够在运行时(第三阶段)实现对类的分析及使用任意Method方法。
Class类
程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标志,虚拟机可利用它使用运行时信息选择相应的方法执行。Java中保存这些信息的类被称为Class类。
获取Class对象的三种方法:
(1)Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象,需要传入含包名的全类名
eg.
ClassA A=new ClassA();
Class CA=Class.forName("java.class_test.ClassA");
(2)类名.class:通过类名的属性class获取
eg.
ClassA A=new ClassA();
Class CA=ClassA.class;
(3)对象.getClass():该方法继承自Object类
eg.
ClassA A=new ClassA();
Class CA=A.getClass;
通常方法三更常用
常用的API
运行时查看/设置域
关键是使用Field类中的get(),set()方法
示例:
利用setAccessible()方法可实现对private成员的访问
相关API:
使用示例:
在运行时将一个A[ ]类型的数组改成B[ ]类型,并修改数组长度
方法指针
Method类中提供了invoke()方法,来调用Method对象中的方法。对于声明为private的方法,仍然可用设置isAccessible()的方法实现对私有方法的访问。
示例
Class ac=a1.getClass();
Method obj=ac.getDeclaredMethod("setA", int.class);
obj.invoke(a1,5);
应当注意的是:invoke()方法的参数及返回值,都是类类型而非基本类型,若为基本类型则用自动打包机制将其打包成类。若调用的是静态方法,则invoke()方法的第一个参数为null。
下面给出几个关于继承设计的忠告: