反射:还原一个类的基本信息

简述

反射是在运行时而非编译时动态获取类型的信息(接口信息,成员信息,方法信息,构造方法信息等)然后依据这些动态获取到的信息创建对象,访问修改成员,调用方法等。反射可以在运行时判断任意一个对象所属的类,任意一个类的成员变量和方法,调用任何一个类的方法,构造任意一个类的对象;生成动态代理

可通过Class.forName(“类名”)方法可以访问返回一个指定类名的类对象,因为在java里面任何一个class都要装载在虚拟机上才能运行,所以这方法的作用是装载类而用。

当我们获取到Class对象后,通过Field字段,Method字段,Constructor字段,和相应的方法分别可以得到类中的属性,普通方法,构造方法。

获取类中属性和方法

1.创建一个类 Student

package Project;

public class Student {
    private String name;
    public String sex;
    int age;
    protected int id;

    public Student() {    }

    public Student(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {        return name;    }

    public void setName(String name) {        this.name = name;    }

    public void show() {    }

    public void init(String name,int id){}
}

2.创建一个测试类用于打印Student中的基本信息

package Project;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Text {
    public static void main(String[] args) throws ClassNotFoundException {
        //第一种方法
        //Class stu=Project.Student.class;
        //第二种方法(需要先创建对象 然后通过对象获得Class)
        //Student student=new Student();
        //Class stu=student.getClass();
        //第三种方法(推荐使用)
        Class stu=Class.forName("Project.Student");//得到类的Class对象

        StringBuffer sb=new StringBuffer();//用于保存需要反射类中的信息

        //                    得到类的修饰符                        类名
        sb.append(Modifier.toString(stu.getModifiers())+"  class  "+stu.getName()+" {\n");

        Field field[]=stu.getDeclaredFields();//得到所有的属性
        for(Field fd:field){     //属性的访问修饰符                     返回值类型              属性名
            sb.append("\t"+Modifier.toString(fd.getModifiers())+" "+fd.getType().getName()+" "+fd.getName()+" \n");

        }

        //得到普通方法
        Method[] modifier=stu.getDeclaredMethods();//得到所有的普通方法

        for(Method md:modifier){//       方法访问修饰符                 返回值类型                       方法名
            sb.append("\t"+Modifier.toString(md.getModifiers())+" "+md.getReturnType().getName()+" "+md.getName()+" (");
            //  得到方法的所有返回值
            Class returns[]=md.getParameterTypes();//因为方法的返回值可能不止一个(也可能没有)所以用数组存放所有返回值
            for(Class rt:returns){//如果方法的返回值不是最后一个  就用“,”隔开
                if(rt!=returns[returns.length-1])  sb.append(rt.getName() +",");
                else sb.append(rt.getName());
            }
            sb.append("){\n\t}\n");
        }

        //得到构造函数
        Constructor constructor[]=stu.getDeclaredConstructors();
        for(Constructor con:constructor){//构造方法的访问修饰符      构造方法名就是类名
            sb.append("\t"+Modifier.toString(con.getModifiers())+"  "+stu.getName()+"(");
            Class reterns[]=con.getParameterTypes();//得到所有返回值
            for(Class rt:reterns){
                if(rt!=reterns[reterns.length-1])  sb.append(rt.getName()+",");
                else sb.append(rt.getName());
            }
            sb.append("){\t}\n");
        }

        sb.append("\n}");
        System.out.println(sb);
    }
}

3.运行结果:


类中的基本信息已经可以获取到了,至于方法的参数列表就不重要了,我们只需知道它的参数类型就可以调用。

总结

我们可以运行期间通过Method得到类中的方法,然后调用对应的方法。也可以通过Constructor得到对应的构造方法,得到该对象。反射在Java中的用处还是挺多的,在JavaSE中可能不怎么会出现。在后面JavaEE的框架中用处很多。或许有人会这么说:无反射,无框架。其实也不无道理。

猜你喜欢

转载自blog.csdn.net/chianz632/article/details/80173348