Bootstrap

反射-----详细深入讲解

什么是反射

1.什么是反射

反射是一种获取类信息的能力

2.什么是类信息

方法,变量,接口,父类,构造器,类名,类的修饰方式

为什么会有反射?

需要获取类信息

对象也可以获取到类信息,但是对象获取的类信息十分有限。

反射是如何工作的?

磁盘阶段:xxx.java----javac---->xxx.class

类对象阶段:通过java命令将.class文件加载到方法区,方法区中的xxx.class文件包含所有的类信息,叫做类对象

反射是从类对象当中获取信息的

运行时阶段:在堆内存当中创建对象,在栈内存中执行main方法 ,在堆栈当中运行

获取类信息的三种方式

想要通过反射获取类信息必须进入到类对象阶段,可以通过以下三种方式

1.磁盘阶段 通过 Class.forName('全类名')

全类名:包名.类名 磁盘阶段的是数据以文件形式进行存储的 包名就是文件的地址,类名就是文件的名称

2.类对象阶段 通过类名.class

3.运行时阶段 已经创建过类对象,通过对象名.getClass()

示例

package Reflect;

public class Student {
    private String name="张三";
    public Integer age=18;
    Character sex='男';
    protected Double height=188.5;
}
package Reflect;
//想要获取类信息,就必须进入类对象阶段
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        Class class1=Class.forName("Reflect.Student");//磁盘阶段
        Class class2=Student.class;//类对象阶段
        Student student=new Student();
        Class class3=student.getClass();//运行阶段

        System.out.println(class1==class2);//==判断对象的地址是否一致
        System.out.println(class2==class3);
    }
}

创建同一个类的对象指向同一个类对象,因此是同一个地址,即方法区当中的类对象

 执行结果

获取类信息

1.获取变量

getDeclaredFields:获取全部的全局变量信息,并且打印

getField:获取public修饰的全局变量信息,并且打印

getDeclaredField:获取指定的变量,所有类型都可以获取

package Reflect;

import java.lang.reflect.Field;
import java.util.Arrays;

//想要获取类信息,就必须进入类对象阶段
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class class1=Class.forName("Reflect.Student");
        //getDeclaredFields获取全部的全局变量信息,并且打印
        Field[] files=class1.getDeclaredFields();
        System.out.println(Arrays.toString(files));
        //getField获取public修饰的全局变量信息,并且打印
        Field[] files1=class1.getFields();
        System.out.println(Arrays.toString(files1));
        System.out.println("**************");
        //getDeclaredField获取指定的变量,所有类型都可以获取
        Field nameField=class1.getDeclaredField("name");
        System.out.println(nameField);
        Field ageFleid=class1.getDeclaredField("age");
        System.out.println(ageFleid);
        Field heightFleid=class1.getDeclaredField("height");
        System.out.println(heightFleid);

        System.out.println("**************");
//        Field nameField1=class1.getField("name");
//        System.out.println(nameField1);
        Field ageFleid1=class1.getField("age");
        System.out.println(ageFleid1);
//        Field heightFleid1=class1.getField("height");
//        System.out.println(heightFleid1);
    }
}

执行结果

2.获取方法

getDeclaredMethods:获取全部方法

getMethods:获取public修饰的方法

getDeclaredMethod:获取指定的方法,可以获取任何修饰符修饰的方法

package Reflect;

public class Student {
    private String name="张三";
    public Integer age=18;
    Character sex='男';
    protected Double height=188.5;
    public String color="蓝色";
    public void run(){}
    private int getAge(int age){
        return age;
    }
    void aaa(String name,Integer height){

    }
    protected void haha(String name,int age){

    }
}
package Reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

//想要获取类信息,就必须进入类对象阶段
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class class1=Class.forName("Reflect.Student");
        //getDeclaredMethods获取全部方法
        Method[] methods=class1.getDeclaredMethods();
        System.out.println(Arrays.toString(methods));
        //getMethods获取public修饰的方法
        Method[] methods1=class1.getMethods();
        System.out.println(Arrays.toString(methods1));
        System.out.println("************");
        //getDeclaredMethod获取指定的方法,可以获取任何修饰符修饰的方法
         Method getAge=class1.getDeclaredMethod("getAge", int.class);
        System.out.println(getAge);
        Method aaa=class1.getDeclaredMethod("aaa", String.class, Integer.class);
        System.out.println(aaa);
        Method run=class1.getDeclaredMethod("run");
        System.out.println(run);
        Method haha=class1.getDeclaredMethod("haha", String.class, int.class);
        System.out.println(haha);
        System.out.println("**********");
        Method run1=class1.getMethod("run");
        System.out.println(run1);

    }
}

执行结果

3.获取构造器

getConstructors:获取public修饰的所有构造器

getDeclaredConstructors:获取全部的构造器

getDeclaredConstructor:获取指定的构造器,所有都可以获取

getConstructor:获取指定的public修饰的构造器

package Reflect;

public class Student {
    private String name="张三";
    public Integer age=18;
    Character sex='男';
    protected Double height=188.5;
    public String color="蓝色";
    public void run(){}
    private int getAge(int age){
        return age;
    }
    void aaa(String name,Integer height){

    }
    protected void haha(String name,int age){

    }
    private Student(){}
    public Student(String name,Integer age){}

    public Student(String name, Integer age, Character sex, Double height, String color) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.height = height;
        this.color = color;
    }
}
package Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

//想要获取类信息,就必须进入类对象阶段
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        //getConstructors获取public修饰的构造器
        Class class1=Class.forName("Reflect.Student");
        Constructor[] constructors=class1.getConstructors();
        System.out.println(Arrays.toString(constructors));
        //getDeclaredConstructors获取全部的构造器
        System.out.println("*************");
        Constructor[] constructors1=class1.getDeclaredConstructors();
        System.out.println(Arrays.toString(constructors1));
        System.out.println("*************");
        //getDeclaredConstructor获取指定的构造器,所有都可以获取
        Constructor constructor1= class1.getDeclaredConstructor();
        System.out.println(constructor1);
        Constructor constructor2=class1.getDeclaredConstructor(String.class,Integer.class);
        System.out.println(constructor2);
        Constructor constructor3=class1.getDeclaredConstructor(String.class,Integer.class,Character.class,Double.class,String.class);
        System.out.println(constructor3);
        System.out.println("*************");
        //getConstructor获取指定的public修饰的构造器
        Constructor constructor4=class1.getConstructor(String.class,Integer.class);
        System.out.println(constructor4);
        Constructor constructor5=class1.getConstructor(String.class,Integer.class,Character.class,Double.class,String.class);
        System.out.println(constructor5);


    }
}

执行结果

使用类信息

创建对象

private修饰的数据,想要使用需要通过setAccessible(true)暴力反射,default和protected修饰就不需要暴力反射,

package Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

//想要获取类信息,就必须进入类对象阶段
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //getConstructors获取public修饰的构造器
        Class class1=Class.forName("Reflect.Student");
       
        Constructor constructor=class1.getDeclaredConstructor(String.class,Integer.class);
        //创建对象
        Student student1=(Student) constructor.newInstance("aaa",18);//需要强转成Student类的对象,默认为Object
        //private修饰的数据,想要使用需要用到暴力反射
        Constructor constructor1=class1.getDeclaredConstructor();
        constructor1.setAccessible(true);
        Student student2=(Student) constructor1.newInstance();
        //default和protected修饰就不需要暴力反射


    }
}

调用方法

通过invoke方法调用方法

package Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

//想要获取类信息,就必须进入类对象阶段
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //getConstructors获取public修饰的构造器
        Class class1=Class.forName("Reflect.Student");

        Constructor constructor=class1.getDeclaredConstructor(String.class,Integer.class);
        //创建对象
        Student student1=(Student) constructor.newInstance("aaa",18);//需要强转成Student类的对象,默认为Object

        Method run=class1.getDeclaredMethod("run");
        run.invoke(student1);//所有的方法要想运行,必须在对象当中开辟内存空间

        Method getAge = class1.getDeclaredMethod("getAge", int.class);
        getAge.setAccessible(true);//private修饰需要暴力反射
        getAge.invoke(student1,20);

        Method aaa = class1.getDeclaredMethod("aaa", String.class, Integer.class);
        aaa.invoke(student1,"gloria",20);

        Method haha = class1.getDeclaredMethod("haha", String.class, int.class);
        haha.invoke(student1,"admin",30);



    }
}

执行结果

获取和设置变量

通过变量.set设置变量值

变量.get获取变量值

package Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

//想要获取类信息,就必须进入类对象阶段
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //getConstructors获取public修饰的构造器
        Class class1=Class.forName("Reflect.Student");

        Constructor constructor=class1.getDeclaredConstructor(String.class,Integer.class);
        //创建对象
        Student student1=(Student) constructor.newInstance("aaa",18);//需要强转成Student类的对象,默认为Object

        Field name = class1.getDeclaredField("name");
        name.setAccessible(true);//private修饰,需要暴力反射
        name.set(student1,"gloria");
        System.out.println(name.get(student1));

        Field age = class1.getDeclaredField("age");
        age.set(student1,20);
        System.out.println(age.get(student1));

        Field sex = class1.getDeclaredField("sex");
        sex.set(student1,'女');
        System.out.println(sex.get(student1));

        Field height = class1.getDeclaredField("height");
        height.set(student1,188.9);
        System.out.println(height.get(student1));



    }
}

执行结果

示例

 获取该类的构造方法来构造对象,获取该类的名称和该类中每一个变量的名称和方法的名称、并执行相关方法。给每一个变量赋值。并获取值,执行每一个构造方法,执行相应的方法

package Reflect;

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

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
package Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

//想要获取类信息,就必须进入类对象阶段
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class class1=Class.forName("Reflect.Student");
        System.out.println("类名************");
        System.out.println(class1.getName());//获取类名
        System.out.println("变量名**********");
        Field[] parameters = class1.getDeclaredFields();
        System.out.println(Arrays.toString(parameters));
        System.out.println("方法名**********");
        Method[] methods = class1.getDeclaredMethods();
        System.out.println(Arrays.toString(methods));
        System.out.println("构造方法*********");
        Constructor[] constructors=class1.getConstructors();
        System.out.println(Arrays.toString(constructors));
        System.out.println("构造方法的获取和调用***********");
        Constructor constructor1=class1.getDeclaredConstructor(String.class,int.class,String.class);
        System.out.println(constructor1);
        System.out.println("创建对象***********");
        Student student1=(Student) constructor1.newInstance("aaa",20,"沧州");
        System.out.println("设置变量***********");
        Field name = class1.getDeclaredField("name");
        name.setAccessible(true);
        name.set(student1,"小红");
        System.out.println(name.get(student1));

        Field age = class1.getDeclaredField("age");
        age.setAccessible(true);
        age.set(student1,23);
        System.out.println(age.get(student1));

        Field address = class1.getDeclaredField("address");
        address.setAccessible(true);
        address.set(student1,"河北");
        System.out.println(address.get(student1));
        System.out.println("调用方法*******************");
        Method getName = class1.getDeclaredMethod("getName");
        getName.invoke(student1);

        Method getAge = class1.getDeclaredMethod("getAge");
        getAge.invoke(student1);

        Method getAddress = class1.getDeclaredMethod("getAddress");
        getAddress.invoke(student1);

        Method setName = class1.getDeclaredMethod("setName",String.class);
        setName.invoke(student1,"gloria");

        Method setAge = class1.getDeclaredMethod("setAge", int.class);
        setAge.invoke(student1,20);

        Method setAddress = class1.getDeclaredMethod("setAddress", String.class);
        setAddress.invoke(student1,"河北");
        System.out.println("最终执行结果*************");
        System.out.println(name.get(student1));
        System.out.println(age.get(student1));
        System.out.println(address.get(student1));




    }
}

 执行结果

欢迎大家点赞,收藏,评论加关注呦!!!!

;