JAVA: 反射的学习 (天天向上系列)

JAVA 反射(Reflection)是指程序可以访问、检测和修改它自身状态或行为的能力。


反射分为几种:

Class类(java.lang.Class)
获取构造器 Constructor
获取成员变量 Field
获取方法 Method
获取数组 Array


Class类(java.lang.Class)

说白了,就是 反射的入口:

解释如下:

1.Class是反射操作的入口。
2.每个加载到内存的对象,JVM都会实例化一个Class的对象来描述它。
3.Class的对象反射它所表示的对象。
4.Class对象存储的被反射类的信息包括:
    类名
    继承性
    实现的接口
    方法

    成员


假如我现在有一个Mother 类

public class Mother {
    /*
     定义 Mother 类及其属性(身高、体重、年龄)和方法(工作、做家务);
     */
    private  String high;
    private  String weight;
    private  String age;
    Mother(){

    }
    Mother(String high,String weight,String age){
        this.high = high;
        this.weight = weight;
        this.age = age;
        System.out.println("反射构造函数");
        System.out.println(high+" | "+weight+" | "+age);

    }
    public void setWeight(String weight) {
        this.weight = weight;
    }

    public void setHigh(String high) {
        this.high = high;
    }

    public void setAge(String age) {
        this.age = age;
    }
    public void getAge(){
        System.out.println(this.age);
    }

    public void getHigh() {
        System.out.println(this.high);
    }

    public void getWeight() {
        System.out.println(this.weight);
    }

    public void work(){

    }
    public void homework(){

    }
}

我先获得Class 类 三种方法:  第三种*** 代表 类的路径

Class cls = Mother.class; 
Class cls = new Mother().getClass();
Class cls = Class.forName("****");

 当获得class 后 ,开始获取构造器

获取构造器 Constructor

        Class cls = new Mother().getClass();
        Constructor constructor[] = cls.getDeclaredConstructors();
        try {
            constructor[1].setAccessible(true);
            Object object = constructor[1].newInstance(new Object[]{"A","B","C"});
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

获取构造器集合, 并设置访问权限.

对构造器利用Object  进行实例化一个对象,设置身高为 A ,体重为 B ,年龄为 C

结果如下:



获取成员变量 Field

获取成员变量:

每个成员变量有类型

java.lang.reflect.Field 为我们提供了获取当前对象的成员变量的类型,和重新设值的方法。

获取变量的类型

类中的变量分为两种类型:基本类型引用类型

  • 基本类型( 8 种) 
    • 整数:byte, short, int, long
    • 浮点数:float, double
    • 字符:char
    • 布尔值:boolean
  • 引用类型 
    • 所有的引用类型都继承自 java.lang.Object
    • 类,枚举,数组,接口都是引用类型
    • java.io.Serializable 接口,基本类型的包装类(比如 java.lang.Double)也是引用类型

java.lang.reflect.Field 提供了两个方法获去变量的类型:

  • Field.getType():返回这个变量的类型
  • Field.getGenericType():如果当前属性有签名属性类型就返回,否则就返回 Field.getType()



    获取任意指定名字的成员

    public Field getDeclaredField(String fieldName)

    获取全部存到集合中的话:

    Field []field = cls.getDeclaredFields();   

    

实例:  

    我现在 反射构造器 将 Mother 类中 high 设置为 "A" , weight 设置为 "B" ,  age 设置为 5 ;

    通过反射集合   获取所有的私有变量. (私有和保护类型的必须设置 可访问权限 : .setAccessible(true);)

    然后输出 反射得到的 变量类型,名称以及 值.

 try {
            constructor[1].setAccessible(true);
            Mother mother = (Mother) constructor[1].newInstance("A","B",5);
            Field []field = cls.getDeclaredFields();

            for( Field fieldidex: field){
                fieldidex.setAccessible(true);
                System.out.println("field -> type: "+fieldidex.getType()+" name: "+fieldidex.getName() + " value : "+
fieldidex.get(mother));
} } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); }

获取方法 Method

获得 类中的方法, 并 调用 类成员方法, 进行修改

实例: 

用 method 获取 setAge 方法,  并调用 invoke 实现 调用 setAge 方法 进行 数值修改

        try {
            constructor[1].setAccessible(true);
            Mother mother = (Mother) constructor[1].newInstance("A","B",5);
            Field []field = cls.getDeclaredFields();

            for( Field fieldidex: field){
                fieldidex.setAccessible(true);
                System.out.println("field -> type: "+fieldidex.getType()+" name: "+fieldidex.getName());
                if (fieldidex.getName()=="age"){
                    System.out.println("value : "+fieldidex.getInt(mother) );
                }
            }
            Method method = cls.getDeclaredMethod("setAge", int.class);
            method.invoke(mother,20);

            System.out.println("field -> after change :  type: "+field[2].getType()+" name: "+field[2].getName() +" value : "+field[2].getInt(mother));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

123

猜你喜欢

转载自blog.csdn.net/sizaif/article/details/80733703
今日推荐