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);
        }
    }
}

       

                

getFields、      getDeclareFields方法的使用 运行结果

 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异常!