Java学习-Java高级-反射

本文深入探讨了Java的反射机制,包括其概念、功能以及在加载类、查看属性和方法、创建对象等方面的应用。通过代码示例展示了如何通过反射获取并使用构造方法、成员方法以及成员变量。此外,还提供了实际场景,如构建通用工具和灵活框架,来说明反射的重要性。
摘要由CSDN通过智能技术生成

Java高级-反射

反射概述

什么是反射

在程序运行过程中分析类的一种能力

反射能做什么?

  • 分析类
    &empsp;&empsp;&empsp;&empsp;加载并初始化一个类
    &empsp;&empsp;&empsp;&empsp;查看类的所有属性和方法
  • 查看并使用对象
    &empsp;&empsp;&empsp;&empsp;查看一个对象的所有属性和方法
    &empsp;&empsp;&empsp;&empsp;使用对象的任意属性和方法

反射的应用场景

  • 构建通用的工具
  • 搭建具有高度灵活性和扩展性的系统框架
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    代码演示
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //需求:获取class对象
        //方式一
        Student stu = new Student();
        Class clazz1 = stu.getClass();

        //方式二
        Class clazz2 = Student.class;

        //方式三
        Class clazz3 = Class.forName("cn.itcast.demo1.Student");

        //思考:如何验证这三个Class对象是同一个对象?
        System.out.println(clazz1 == clazz2);   //true
        System.out.println(clazz2 == clazz3);   //ture
    }
}
//学生类
public class Student {
}

运行结果
在这里插入图片描述

反射方式获取构造方法并使用

在这里插入图片描述
代码演示

import java.lang.reflect.Constructor;

public class ReflectDemo1 {
    public static void main(String[] args) throws Exception {
        //需求:通过反射的方式创建:Student类型的对象
        //1. 获取Student类的字节码文件对象
        Class clazz = Class.forName("cn.itcast.demo2.Student");
        //2. 根据第一步获取到的字节码文件对象,获取指定的构造器对象
        //2.1 获取公共无参构造
        Constructor con1 = clazz.getConstructor();
        System.out.println(con1);

        //2.2 获取公共有参构造
        Constructor con2 = clazz.getConstructor(String.class);
        System.out.println(con2);

        //2.3 获取私有有参构造
        Constructor con3 = clazz.getDeclaredConstructor(int.class);
        System.out.println(con3);

        //2.4 获取Student类的所有公共的构造函数
        System.out.println("--------------------");
        Constructor[] cons = clazz.getConstructors();
        //遍历数组
        for (Constructor con : cons) {
            System.out.println(con);
        }
        //2.2 获取公共有参构造
        Constructor con4 = clazz.getConstructor(String.class);
        System.out.println(con4);

        //获取构造器的名字,看看它是哪个类的构造
        String name = con4.getName();
        System.out.println(name);
        //3. 根据构造器对象和参数,创建对应的Student对象
        Student stu =(Student) con4.newInstance("张三");
        //4. 打印结果
        System.out.println(stu);
    }
}
//学生类
public class Student {
    //公共的无参构造
    public Student() {};

    //公共的带参构造
    public Student(String name) {
        System.out.println("您录入的name的值是:" + name);
    }

    //私有的带参构造
    private Student(int age) {
        System.out.println("您录入的age的值是:" + age);
    }
}

运行结果
在这里插入图片描述

反射方式获取成员方法并使用

在这里插入图片描述
代码演示

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

public class ReflectDemo1 {
    public static void main(String[] args) throws Exception {
        //需求:通过反射获取Student类中的成员方法并调用
        //1. 获取Student类的字节码文件对象
        Class clazz = Class.forName("cn.itcast.demo3.Student");

        //2. 获取该类的构造器对象,然后创建Student类的对象
        Constructor con = clazz.getConstructor();
        Student stu =(Student) con.newInstance();
        //System.out.println(stu);
        //3. 获取该类的成员方法对象,然后调用此方法
        //3.1 调用公共的空参方法
        Method method1 = clazz.getMethod("show1");
        //打印方法对象
        System.out.println(method1);
        //打印方法名
        System.out.println(method1.getName());
        //调用此方法
        method1.invoke(stu);
        System.out.println("------------------");

        //3.2 公共的带参方法
        Method method2 = clazz.getMethod("show2", int.class);
        //调用方法
        method2.invoke(stu, 100);
        System.out.println("------------------");


        //3.3 调用私有的带参方法
        Method method3 = clazz.getDeclaredMethod("show3", int.class, int.class);
        //开启暴力反射
        method3.setAccessible(true);
        //调用此方法
        int sum =(int)method3.invoke(stu, 10, 20);
        System.out.println("您录入的两个数的和是:" + sum);
        System.out.println("------------------");

        //3.4 获取Student类中所有的成员方法
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
    }
}
public class Student {
    //公共的空参方法
    public void show1() {
        System.out.println("我是公共的空参方法");
    }

    //公共的带参方法
    public void show2(int a) {
        System.out.println("我是公共的带参方法,您传入的a的值是:" + a);
    }

    //私有的带参方法
    private int show3(int a, int b) {
        System.out.println("我是私有的带参方法");
        return a + b;
    }
}

运行结果
在这里插入图片描述

案例:通过反射获取方法并使用

在这里插入图片描述
代码演示

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

public class ReflectDemo1 {
    public static void main(String[] args) throws Exception {
        //需求:通过反射获取类的setter方法,使用该方法为属性赋值
        //1. 通过反射获取Student类的字节码文件对象
        Class clazz = Class.forName("cn.itcast.demo4.Student");

        //2. 通过反射获取Student类的构造方法,并创建该类的对象
        Constructor con = clazz.getConstructor();
        Student stu = (Student)con.newInstance();
        //3. 获取到指定的setName()方法,给Student对象设置值
        Method method1 = clazz.getMethod("setName", String.class);
        //调用此方法
        method1.invoke(stu,"张三");
        //4. 打印学生对象
        System.out.println(stu);
    }
}
//标准的JavaBean类,学生类
public class Student {
    //成员变量
    private String name;


    //空参构造
    public Student() {

    }

    //带参构造
    public Student(String name) {
        this.name = name;
    }

    //getXxx和setXxx方法
    public String getName() {
        return name;
    }

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

    //toString()方法,用来打印该对象的各个属性值的
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

运行结果
在这里插入图片描述

反射方式获取成员变量并使用

在这里插入图片描述
代码演示

import java.lang.reflect.Field;

public class ReflectDemo1 {
    public static void main(String[] args) throws Exception{
        //需求:通过反射获取成员变量并使用
        //1. 获取Student类的字节码文件对象
        Class clazz = Class.forName("cn.itcast.demo5.Student");
        //2. 通过字节码文件对象获取构造器对象,然后创建学生类对象
        /*Constructor con = clazz.getConstructor();
        Student stu = (Student) con.newInstance();*/
        Student stu = (Student)clazz.getConstructor().newInstance();    //链式编程
        //3. 设置学生对象的各个属性值
        //3.1 设置姓名
        Field field1 = clazz.getField("name");
        field1.set(stu, "李四");

        //3.2 设置年龄
        Field field2 = clazz.getDeclaredField("age");
        //开启暴力反射
        field2.setAccessible(true);
        field2.set(stu, 20);
        //4. 打印学生对象
        System.out.println(stu);
    }
}
//学生类
public class Student {
    //公共属性
    public String name;
    //私有的属性
    private int age;

    //用来打印对象的各个属性值的

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

运行结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值