搞懂反射我建议选这篇

本文介绍了Java反射机制,通过Class类获取类的信息并创建对象,包括三种创建对象的方式,以及如何访问和操作类的属性、构造方法和成员方法。反射允许在运行时检查和修改程序行为,包括访问private资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍

Reflection(反射) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查。被private封装的资源只能类内部访问,外部是不行的,但反射能直接操作类私有属性。

反射可以在运行时获取一个类的所有信息,(包括成员变量,成员方法,构造器等),并且可以操纵类的字段、方法、构造器等部分。通俗点总结就是不通过创建对象的方式来访问类的属性,并且能够访问private修饰的属

性。

Class类

Java反射的基础是Class类,它是Java反射的入口。Class类提供了获取类的构造函数、方法、字段、注解等信息的方法。

创建对象

Class.forName(“类的全路径”)( 例如:com.hqyj.core.io.serializestream.Student)

类名.class

类的对象.getClass();( 不建议)

测试代码

public static void test01() throws Exception{
        //反射,拿到了类的所有信息,可以走后门
        //方式一
        //创建类的Class对象
        System.out.println("===================================");
        System.out.println("方式一");
        Class c1=Class.forName("com.HQSecond.day9.Student");
        //创建Student对象
        Student stu1=(Student) c1.newInstance();
        System.out.println(stu1);

        System.out.println("===================================");
        System.out.println("方式二");
        Class c2=Student.class;
        Student stu2=(Student) c2.newInstance();
        System.out.println(stu2);

        System.out.println("===================================");
        System.out.println("方式三");
        Class c3=new Student().getClass();
        Student stu3=(Student) c3.newInstance();
        System.out.println(stu3);
    }

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2LLmwLOv-1688183743916)(E:\myapp\typora\笔记文件夹\java第二阶段\imgs-2\创建对象测试结果.png)]

属性

Fields[] fields; (存储的是类的成员变量)

getField() 根据名字获取public修饰的变量
getFields() 返回类中public修饰的成员变量
getDeclaredField()  根据名字获取所有变量
getDeclaredFields()  返回类中所有的成员变量

测试代码

        public static void test02() throws Exception{
        //创建类的Class对象
        Class c1=Class.forName("com.HQSecond.day9.Student");
        //创建Student对象
        Student stu1=(Student) c1.newInstance();
    
        //根据指定名字获取成员变量Field对象中包含了变量的属性(权限修饰符、类型、名字)
        System.out.println("=========================================");
        System.out.println("根据指定名字获取成员变量:");
        Field  f= c1.getField("name");
        System.out.println("变量的名称:"+f.getName());
        System.out.println("变量的类型:"+f.getType().getName());

        System.out.println("=========================================");
        System.out.println("获取类中所有public成员变量:");
        Field[] fields = c1.getFields();
        for (Field f1:fields) {
            System.out.print(f1.getName()+"     ");
            System.out.println(f1.getType());
        }
        System.out.println("=========================================");
        System.out.println("获取类中所有成员变量:");
        Field[] fields1 = c1.getDeclaredFields();
        for (Field f1 : fields1) {
            System.out.print(f1.getName()+"     ");
            System.out.println(f1.getType());
        }
        System.out.println("=========================================");
        System.out.println("给指定的变量赋值:");
        System.out.println("public变量:");
        Field f2 = c1.getDeclaredField("name");
        f2.set(stu1,"Bob");//赋值
        System.out.println(stu1.getName());//获取

        System.out.println("private变量:");
        Field f4 = c1.getDeclaredField("sex");
        给private修饰的变量赋值,需要设置暴力反射
        f4.setAccessible(true);
        f4.set(stu1,"male");//赋值
        System.out.println(stu1.getSex());//获取

    }
   

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a0fMArB7-1688183743918)(E:\myapp\typora\笔记文件夹\java第二阶段\imgs-2\反射变量测试.png)]

构造方法

Constructors[] constructors;(存储的是类的构造方法)

getConstructors();获取类中的所有构造方法

getConstructor();获取无参的构造方法

getConstructor(String.class, int.class, char.class);
获取有参的构造方法,表明第一个参数为String类型,第二个为int类,第三个为char

测试代码

 public static void test03() throws Exception{
        //方式二 创建class对象
        Class c1=Student.class;

        System.out.println("=========================================");
        System.out.println("获取类中的构造方法:");
        Constructor[] cons = c1.getConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("=========================================");
        System.out.println("获取无参的构造方法,创对象:");
        //获取无参的构造方法 创对象---->调用构造方法 调用构造方法----->创对象
        Constructor con1 = c1.getConstructor();
        //通过无参构造方法创建Student对象
        Student Stu1=(Student)con1.newInstance();
        System.out.println(Stu1);
        System.out.println("=========================================");
        System.out.println("获取有参的构造方法,创对象:");
        //获取有参的构造方法
        Constructor con2 = c1.getConstructor(String.class, Integer.class);
        // 通过有参构造创建对象
        Student stu2=(Student)con2.newInstance("大黄",5);
        System.out.println(stu2);
        System.out.println("=========================================");
        System.out.println("获取有参的构造方法,创对象:");
        Constructor con3 = c1.getConstructor(String.class, Integer.class,String.class,String.class);
        Student stu3=(Student)con3.newInstance("Alice",18,"female","ball");
        System.out.println(stu3.toString());

    }

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RtWz6327-1688183743918)(E:\myapp\typora\笔记文件夹\java第二阶段\imgs-2\反射构造方法测试.png)]

成员方法

Methods[] methods;(存储的是类的成员方法)

getMethod("eat", String.class);(参数1:方法的名称, 参数2:方法形参类型)

测试代码

  public static void test04()throws Exception{
        Class c= Class.forName("com.HQSecond.day9.Student");
        Student Stu1=(Student)c.newInstance();
        Stu1.name="Jack";
        //通过反射调用类中的成员方法   参数1:方法的名称, 参数2:方法形参类型
        Method m = c.getMethod("getName");
        //执行方法,传递参数
        System.out.println(m.invoke(Stu1));
        //测试2 用set方法设置,get方法获取
        Method m1 = c.getMethod("setHobby", String.class);
        m1.invoke(Stu1,"ball");
        Method m2 = c.getMethod("getHobby");
        System.out.println(m2.invoke(Stu1));

    }

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9yXZslo2-1688183743918)(E:\myapp\typora\笔记文件夹\java第二阶段\imgs-2\反射方法测试.png)]

用到的全部代码

student类


import java.io.Serializable;

public class Student implements Serializable {
    //成员变量
    //声明一个固定的序列号,此时无论去改变类,序列号都不会变。
    public static final long serialVersionUID=12345;
    public String name;
    public Integer age;
    private String sex;
    protected String hobby;
    //构造方法
    public Student(){}
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

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

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


     //成员方法
    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", hobby='" + hobby + '\'' +
                '}';
    }
}

运行的全部代码

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

public class ReflectTest {
    public static void main(String[] args) throws Exception {
        test01();
        test02();
        test03();
        test04();
    }
    public static void test01() throws Exception{
        //反射,拿到了类的所有信息,可以走后门
        //方式一
        //创建类的Class对象
        System.out.println("===================================");
        System.out.println("方式一");
        Class c1=Class.forName("com.HQSecond.day9.Student");
        //创建Student对象
        Student stu1=(Student) c1.newInstance();
        System.out.println(stu1);

        System.out.println("===================================");
        System.out.println("方式二");
        Class c2=Student.class;
        Student stu2=(Student) c2.newInstance();
        System.out.println(stu2);

        System.out.println("===================================");
        System.out.println("方式三");
        Class c3=new Student().getClass();
        Student stu3=(Student) c3.newInstance();
        System.out.println(stu3);
    }
    public static void test02() throws Exception{
        //创建类的Class对象
        Class c1=Class.forName("com.HQSecond.day9.Student");
        //创建Student对象
        Student stu1=(Student) c1.newInstance();
       

        //根据指定名字获取成员变量Field对象中包含了变量的属性(权限修饰符、类型、名字)
        System.out.println("=========================================");
        System.out.println("根据指定名字获取成员变量:");
        Field  f= c1.getField("name");
        System.out.println("变量的名称:"+f.getName());
        System.out.println("变量的类型:"+f.getType().getName());

        System.out.println("=========================================");
        System.out.println("获取类中所有public成员变量:");
        Field[] fields = c1.getFields();
        for (Field f1:fields) {
            System.out.print(f1.getName()+"     ");
            System.out.println(f1.getType());
        }
        System.out.println("=========================================");
        System.out.println("获取类中所有成员变量:");
        Field[] fields1 = c1.getDeclaredFields();
        for (Field f1 : fields1) {
            System.out.print(f1.getName()+"     ");
            System.out.println(f1.getType());
        }
        System.out.println("=========================================");
        System.out.println("给指定的变量赋值:");
        System.out.println("public变量:");
        Field f2 = c1.getDeclaredField("name");
        f2.set(stu1,"Bob");//赋值
        System.out.println(stu1.getName());//获取

        System.out.println("private变量:");
        Field f4 = c1.getDeclaredField("sex");
        给private修饰的变量赋值,需要设置暴力反射
        f4.setAccessible(true);
        f4.set(stu1,"male");//赋值
        System.out.println(stu1.getSex());//获取

    }
    public static void test03() throws Exception{
        //方式二 创建class对象
        Class c1=Student.class;

        System.out.println("=========================================");
        System.out.println("获取类中的构造方法:");
        Constructor[] cons = c1.getConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("=========================================");
        System.out.println("获取无参的构造方法,创对象:");
        //获取无参的构造方法 创对象---->调用构造方法 调用构造方法----->创对象
        Constructor con1 = c1.getConstructor();
        //通过无参构造方法创建Student对象
        Student Stu1=(Student)con1.newInstance();
        System.out.println(Stu1);
        System.out.println("=========================================");
        System.out.println("获取有参的构造方法,创对象:");
        //获取有参的构造方法
        Constructor con2 = c1.getConstructor(String.class, Integer.class);
        // 通过有参构造创建对象
        Student stu2=(Student)con2.newInstance("大黄",5);
        System.out.println(stu2);
        System.out.println("=========================================");
        System.out.println("获取有参的构造方法,创对象:");
        Constructor con3 = c1.getConstructor(String.class, Integer.class,String.class,String.class);
        Student stu3=(Student)con3.newInstance("Alice",18,"female","ball");
        System.out.println(stu3.toString());

    }
    public static void test04()throws Exception{
        System.out.println("===============================");
        System.out.println("通过反射调用类中的成员方法:");
        Class c= Class.forName("com.HQSecond.day9.Student");
        Student Stu1=(Student)c.newInstance();
        Stu1.name="Jack";
        //通过反射调用类中的成员方法   参数1:方法的名称, 参数2:方法形参类型
        Method m = c.getMethod("getName");
        //执行方法,传递参数
        System.out.println(m.invoke(Stu1));
        //测试2 用set方法设置,get方法获取
        Method m1 = c.getMethod("setHobby", String.class);
        m1.invoke(Stu1,"ball");
        Method m2 = c.getMethod("getHobby");
        System.out.println(m2.invoke(Stu1));

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yjg_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值