java高级编程之反射
1.什么是反射
1.1对反射的简单理解
就像我上面所画的图,反射就相当于一个逆过程,比如我们正常的创建一个对象是通过
Person person = new Person;
但如果我们想通过反射创建一个对象就需要这样
Class clazz = Person.class;
Person person =(Person)clazz.newInstance();
1.2对反射的深入理解
能够分析类能力的程序称为反射,反射机制的功能极其强大反射可以用来:
1.在运行时分析类的能力
2.在运行时检查对象,例如编写一个适用于所有类的toString方法
3.实现泛型数组操作代码
4.利用Method对象,这个对象很像C++中的函数指针
2.Class类
2.1获得Class类对象的三种常用方法
通过运行时类的对象获取Class类对象
Person person = new Person();
Class clazz = person.getClss();
通过全类名获取Class类对象
Class clazz = Class.forName("Person类的全路径");
通过运行时的类名获取Class类对象
Class clazz = Person.class;
我们常用第二种方法获取Class类实例,因为这能更好的体现反射的动态性!提到反射的动态性我觉得有必要来聊一聊编译时和运行时,第一种和第三种方法一样,如果在编译阶段没有找到Person类,那么就会报错(就相当于我们平时说的写死了!)而第三种方法是在运行时阶段去找这个全路径下的类,没有找到才会抛异常(很活。。。很动态。。。)
3.检查类的结构
在java.lang.Reflect包中有三个类Field、Method、Constructor分别用于描述类的字段、方法、和构造器,这三个类都有一个叫getName的方法,用来返回字段,方法,或构造器的名称
Field类有一个getType方法,用来描述字段类型的一个对象,这个对象的类型同样是Class,Method类还有一个报告返回类型的方法,这三个类都有一个名为getModifiers的方法,它将返回一个整数,用不同的0/1位描述所使用的修饰符,如public和static。
Class类中的getFields、getMethods和getConstructors方法将分别返回这个类支持的公共字段、方法和构造器的数组,其中包括超类的共同成员
Class类中的getDeclareFields、getDeclareMethods、getDeclareConstructors方法将分别返回类中声明的全部字段、方法、和构造器的数组,其中包括私有成员、包成员和受保护成员,但不包括超类的成员
package com.atguigu.java;
import java.lang.reflect.Field;
class Person{
public String name;
private int age;
public String address;
public Person(){
}
private Person(String name){
}
}
class Student extends Person{
public char sex;
public void read(){
System.out.println("A student is reading");
}
}
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException {
Class clazz = Class.forName("com.atguigu.java.Student");
Field[] fields = clazz.getFields();
for(Field field : fields){
System.out.println("getFields()方法所打印的字段:"+field);
}
System.out.println("-----------------------");
Field[] declaredFields = clazz.getDeclaredFields();
for(Field field : declaredFields){
System.out.println("getDeclaredFields()方法所打印的字段:"+field);
}
}
}

4.使用反射在运行时分析对象
在编写程序时,如果想要查看的字段名和类型,查看对象中指定字段的内容是一件很容易的事情,而利用反射机制可以查看在编译时还不知道的对象字段。
Class clazz = Class.forName("com.atguigu.java.Student");
Field field1 = clazz.getField("sex");
Object o = clazz.newInstance();
field1.set(o,'女');
Object o1 = field1.get(o);
System.out.println(o1);
如果该字段是一个私有字段,而又想改变它的值的话则需要加一个
field.setAccessible(true);
如果不加则会报IllegalAccessException异常!