Java在运行时识别类和对象的信息,主要有两种方式:一种是传统的RTT1,如今我们写的程序大多是这种方式,它假定我们在编译时就已经知道了所有的类型信息,比如一个类它的构造方法、普通方法有哪些,形参列表是什么等;另一种是反射机制,它允许我们在运行时发现和使用类的信息。
如何理解反射机制呢?
一个大型的工程项目,并不能交由一个人完成所有编写。在对某个类的信息不熟悉,看源代码不现实或需要耗费大量时间,但需要用这个类时,就用到了反射机制,它可以通过Class类的对象,来获取一个未知类的信息,包括它的定义的参数、构造方法和普通方法,并且可以使用它。
通过反射机制或者类的信息,最常用的方法是通过Class类的静态方法:forName(String className) 返回与带有给定字符串名的类或接口相关联的Class对象。这个也是反射机制的一大用处。比如一个美化照片的软件,假设存在一个自动美化的beauti类,当我们有了更好的美化技术,beauti_new类产生了。这时候要将它重新放入软件中调用是十分麻烦的,所有beauti相关的都要重写,但如果使用反射,只需要改字符串名即可。
利用反射获取类的信息:
假设未知类:
package reflect;
public class student {
public String stuno;
private String stuname;
protected int sgrate;
student(String str)
{
System.out.println("默认的构造函数"+str);
}
public student()
{
System.out.println("public的构造函数");
}
public void getstuno()
{
System.out.println("学号是:099999");
}
private void getstuname()
{
System.out.println("学生姓名是:lll");
}
protected void getsgrate()
{
System.out.println("学生成绩是:99");
}
}
测试类:
package reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class exam {
public static void main(String[] args) {
// TODO 自动生成的方法存根
try {
Class clastu=Class.forName("reflect.student");
Field[] cons=clastu.getDeclaredFields();
for(Field c:cons)
{
System.out.println(c);
}
} catch (ClassNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
这里,Field是获取student类中的定义的字段信息,getDeclaredFields() 是获取类中定义的字段信息数组。如果直接用getFields(),是此Class
对象所表示的类或接口的所有可访问公共字段。获取普通方法Methonds,构造方法Constructors都是同理。这里要注意,不加Declared就是获取类中的所有公共部分,包括该类超类的公共字段或函数,加了之后是在这个类中定义的所有字段或函数,包括保护、私有类型。