signed

QiShunwang

“诚信为本、客户至上”

Java反射技术笔记

2021/3/21 0:08:26   来源:

Java反射技术笔记

Java的反射技术说的是在运行状态中,对于任何一个类,我们都能知道这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。这种动态获取对象信息和调用对象方法的功能成为反射机制。

三种方式
(1)Object是Java中所有类的父类,所有Objece中的getClass()可以给所有从Object继承来的类所使用。(了解就行)
例:注:class Animals{…}以下代码都一样,因此省略。


class Animals {
    private String variety;
    private int number;
    public Animals(){       //无参函数
    }
    public Animals(String variety,int number){      //有参函数
        this.variety = variety;
        this.number = number;
    }
    public String getVariety(){
        return variety;
    }
    public void setVariety(String variety){
        this.variety = variety;
    }
    public int getNumber(){
        return number;
    }
    public void setNumber(int number){
        this.number = number;
    }

}

public class zoo{
    public static void main(String[]args) {
        Animals animals = new Animals();
        Class animalsClass = animals.getClass();
        System.out.println(animalsClass);
    }
}

在这里插入图片描述

(2)任何数据类型都有一个静态的class属性。(了解就行)
例:

    public static void main(String[]args) {
        Class animalsClass = Animals.class;
        System.out.println(animalsClass);
    }
}

在这里插入图片描述

★(3)通过Class类里边的静态方法forName(String className),这里括号内String className是反射的类的名称字符串。(掌握)
例:
注:Class animalsClass = Class.forName(“test_2.Animals”);这是后面的animalsClass

    public static void main(String[]args) throws ClassNotFoundException {
        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        System.out.println(animalsClass);
    }
}

在这里插入图片描述
知识点:
一、通过反射技术获取构造方法并使用。
①批量获取构造方法(getConstructors())
public Constructor[] getConstructors();获取所有“公有的”构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法,包括私有的,受保护的。
例:

    public static void main(String[]args) throws ClassNotFoundException,
            NoSuchFieldException {
        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        Constructor[] conArray = animalsClass.getConstructors();
        for(Constructor c : conArray){		//for循环语句打印
            System.out.println(c);
        }
        }
}

在这里插入图片描述

②获取单个构造方法(getConstructor())
public Constructor getConstructor(parameter Types);
public Constructor getDeclaredConstructor(parameter Types);
例:

    public static void main(String[]args) throws ClassNotFoundException,
            NoSuchMethodException {
        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        Constructor con1 = animalsClass.getConstructor(); 	//类型.class
        System.out.println(con1);
    }
}

在这里插入图片描述

可通过newInstance()来产生实例。newInstance()是Constructor类的方法,使用此方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
例:

    public static void main(String[]args) throws ClassNotFoundException,
            NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        Constructor con2 = animalsClass.getConstructor(String.class,int.class);
        Object obj = con2.newInstance("tiger",20);
        System.out.println(obj);
    }
}

在这里插入图片描述

二、通过反射获取成员变量并使用。
①批量获取成员变量。(getFields())
public Field[] getFields();获取所有“公有的”成员变量。
public Field[] getDeclaredFields();获取所有成员变量,包括私有的,受保护的。
例:

    public static void main(String[]args) throws ClassNotFoundException,
            NoSuchFieldException {
        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        Field[] fieldArray = animalsClass.getDeclaredFields();
        for(Field f : fieldArray){	for循环语句打印
            System.out.println(f);
        }
        }
}

在这里插入图片描述

②获取单个成员变量。(getField())
public Field[] getField();获取所有“公有的”成员变量。
public Field[] getDeclaredField();获取所有成员变量,包括私有的,受保护的。
例:

    public static void main(String[]args) throws ClassNotFoundException,
            NoSuchFieldException {
        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        Field field = animalsClass.getDeclaredField("variety");
        System.out.println(field);
        }
}

在这里插入图片描述

赋予或修改成员变量的值:
例:

    public static void main(String[]args) throws ClassNotFoundException,
            NoSuchFieldException, IllegalAccessException, NoSuchMethodException,
            InvocationTargetException, InstantiationException {

        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        //获取成员变量
        Field field = animalsClass.getDeclaredField("variety");
        Object obj = animalsClass.getConstructor().newInstance();
        field.setAccessible(true);  //暴力反射,解出私有限定
        field.set(obj,"tiger");
        System.out.println(((Animals)obj).getVariety());
        //强制把Object类转换成Animals类
        }
}

在这里插入图片描述
三、通过反射获取成员方法并使用
①批量获取成员方法
public Method[] getMethods();获取所有“公有的”方法,包含父类的方法也包含Object类。
public Method[] getDeclaredMethods();获取所有成员方法,包括私有的,不包括继承的。
例:

    public static void main(String[] args) throws ClassNotFoundException,
            NoSuchFieldException, IllegalAccessException, NoSuchMethodException,
            InvocationTargetException, InstantiationException {

        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        Method[] methodArray = animalsClass.getMethods();
        for (Method m : methodArray) {
            System.out.println(m);
        }
    }
}

在这里插入图片描述

②获取单个成员方法
例:

    public static void main(String[] args) throws ClassNotFoundException,
            NoSuchFieldException, IllegalAccessException, NoSuchMethodException,
            InvocationTargetException, InstantiationException {

        Class animalsClass = Class.forName("test_2.Animals");
        //括号里面要注明类所在的包,如果直接在src下面创建类,就不需要。
        Field f = animalsClass.getDeclaredField("variety");     //成员变量名称的字符串
        Object obj = animalsClass.getConstructor().newInstance();
        //newInstance是Construct类里面的一个方法,用来创建该构造方法声明类的新实例。
        f.setAccessible(true);  //解除私有限定
        //获取单个成员方法
        Method m = animalsClass.getMethod("setNumber", int.class);
        //“方法的名称”,方法的类型.class
        m.invoke(obj,20);
        System.out.println(((Animals)obj).getNumber());
    }
}

在这里插入图片描述

注:Object invoke(Object obj,Object…args):是Method类的一个方法,第一个参数是要调用方法的对象,后面的参数是调用方法时所传递的实参。