Java整理程序员

Java反射知识整理

2020-05-19  本文已影响0人  秀儿2020

反射的核心思想就是利用已经装载到内存的字节码获取类的对象的信息。

反射定义

反射是在运行时而非编译时,才知道要操作的类是什么,动态的获取类型的信息,比如接口信息、成员信息、方法信息、构造方法等,根据这些信息去创建对象、访问方法、访问或者修改成员变量。

Class类

每个已加载的类在内部都有一份类信息,每个对象都有指向他所属的类信息的引用。类信息对应的类就是java.lang.Class。Class是一个泛型类。
可通过三种途径获取Class对象。

Class<Date> cls = Date.getClass;
Class<?> cls = Class.forName("java.util.HashMap");
Date date = new Date();
Class<?> clz = date.getClass();

使用Class对象操作字段信息

public class Student {
    private String name;
    public String location;
    public int age;

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

    private void run(){
        System.out.println("this ist the private run method");
    }

    public String getName() {
        System.out.println("this ist the public getName method");
        return name;
    }

    public void setName(String name) {
        System.out.println("this ist the public getName method");
        this.name = name;
    }

    public String getLocation() {
        System.out.println("this ist the public getLocation method");
        return location;
    }

    public void setLocation(String location) {
        System.out.println("this ist the public setLocation method. location = " + location);
        this.location = location;
    }

    public int getAge() {
        System.out.println("this ist the public getAge method");
        return age;
    }

    public void setAge(int age) {
        System.out.println("this ist the public setAge method");
        this.age = age;
    }
}



    private static void getField() throws IllegalAccessException, InstantiationException {
        Class<Student> clz = Student.class;
        Student student = (Student) clz.newInstance();
        Field[] fields = clz.getFields();
        System.out.println("获取所有的public的字段,包括父类的");
        for(Field field : fields){
            System.out.println(field.getName());
        }
        System.out.println("*********************************************");
        System.out.println("获取本类中所有的的字段,包括非public的,但不包括父类的");
        fields = clz.getDeclaredFields();
        for(Field field : fields){
            System.out.println(field.getName());
        }
        System.out.println("*********************************************");
        System.out.println("获取本类或者父类中指定名称的public字段,");
        Field field = null;
        try {
            field = clz.getField("age");
            System.out.println("字段名称 : " + field.getName());
            System.out.println("获取字段的值");
            System.out.println(field.get(student));
            System.out.println("修改字段的值");
            field.set(student,43565);
            System.out.println(field.get(student));
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println("*********************************************");
        System.out.println("获取本类中声明的指定名称的字段");
        try {
            field = clz.getDeclaredField("name");
            field.setAccessible(true);
            System.out.println("字段名称 : " + field.getName());
            System.out.println("修改私有字段的值");
            field.set(student,"修改成功");
            System.out.println(field.get(student));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
    

输出为:

获取所有的public的字段,包括父类的
location
age
*********************************************
获取本类中所有的的字段,包括非public的,但不包括父类的
name
location
age
*********************************************
获取本类或者父类中指定名称的public字段,
字段名称 : age
获取字段的值
0
修改字段的值
43565
*********************************************
获取本类中声明的指定名称的字段
字段名称 : name
修改私有字段的值
修改成功

使用Class对象操作方法

        Class<Student> clz = Student.class;
        Student student = null;
        try {
            student = (Student) clz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println("************************");
        System.out.println("返回所有的public方法,包括父类的");
        Method[] methods = clz.getMethods();
        for(Method method:methods){
            System.out.println(method.getName());
        }
        System.out.println("************************");
        System.out.println("返回本类中声明的所有方法,包括非public的,但不包括父类的");
        methods = clz.getDeclaredMethods();
        for(Method method:methods){
            System.out.println(method.getName());
        }
        System.out.println("************************");
        System.out.println("返回本类和父类中指定名称和参数类型的public方法");
        try {
            Method method1 = clz.getMethod("setLocation",String.class);
            System.out.println(method1.getName());
            method1.invoke(student,"这是地址");
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println("************************");
        System.out.println("返回本类中声明的指定名称和参数类型的方法,包括非public方法");
        try {
            Method method1 = clz.getDeclaredMethod("run");
            System.out.println(method1.getName());
            method1.setAccessible(true);
            method1.invoke(student);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }

运行结果为:

************************
返回所有的public方法,包括父类的
getName
getLocation
setName
setLocation
getAge
setAge
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
************************
返回本类中声明的所有方法,包括非public的,但不包括父类的
getName
run
getLocation
setName
setLocation
getAge
setAge
************************
返回本类和父类中指定名称和参数类型的public方法
setLocation
this ist the public setLocation method. location = 这是地址
************************
返回本类中声明的指定名称和参数类型的方法,包括非public方法
run
this ist the private run method

创建对象和构造方法

Class<Student> clz = Student.class;
        System.out.println("*********************************************");
        System.out.println("获取所有的public构造方法");
        Constructor<Student>[] constructors = (Constructor<Student>[]) clz.getConstructors();
        for(Constructor constructor: constructors){
            System.out.println(constructor);
        }
        System.out.println("*********************************************");
        System.out.println("获取所有的构造方法,包括非public的");
        constructors = (Constructor<Student>[]) clz.getDeclaredConstructors();
        for(Constructor constructor: constructors){
            System.out.println(constructor);
        }
        System.out.println("*********************************************");
        System.out.println("获取指定参数类型的public构造方法");
        Constructor constructor = null;
        try {
            constructor = clz.getConstructor(String.class,String.class,int.class);
            System.out.println(constructor);
            Student s = (Student) constructor.newInstance("this is name","this is location",18);
            System.out.println(s);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println("*********************************************");
        System.out.println("获取指定参数类型的构造方法,包括非public的");
        constructor = null;
        try {
            constructor = clz.getDeclaredConstructor(String.class);
            System.out.println(constructor);
            constructor.setAccessible(true);
            Student s = (Student) constructor.newInstance("this is name");
            System.out.println(s);
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }

运行结果为:

*********************************************
获取所有的public构造方法
public reflect.Student(java.lang.String,java.lang.String,int)
*********************************************
获取所有的构造方法,包括非public的
private reflect.Student(java.lang.String)
public reflect.Student(java.lang.String,java.lang.String,int)
*********************************************
获取指定参数类型的public构造方法
public reflect.Student(java.lang.String,java.lang.String,int)
Student{name='this is name', location='this is location', age=18}
*********************************************
获取指定参数类型的构造方法,包括非public的
private reflect.Student(java.lang.String)
Student{name='this is name', location='null', age=0}

上一篇 下一篇

猜你喜欢

热点阅读