案例挑战—java反射

这里写目录标题

背景

由于在公司自研的新项目架构中使用了大量的反射来提高项目的可复用、灵活性。

项目运用的场景有:

1.程序运行期间动态生成类并进行调用

2.通过反射时间接口的高复用

趁着这个机会博主对反射的基本应用进行汇总和总结。

一、为什么要使用反射?

反射是一项强大的功能。

  1. 它允许你在运行时动态操作类、对象、方法和属性
  2. 它允许你访问类的私有属性和私有方法

二、反射的应用

反射常用应用的思维导图

2.1获取class对象的三种方法

  1. Class.forName("全限定类名")
  2. 类名.class
  3. 对象.getClass();

全限定类名=该类所处的包路径+类名

示例代码

Student类

java 复制代码
package com.wangwei.myreflec1;


public class Student {
    private String name;

    private int age;

    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;
    }
}

Demo1类

java 复制代码
package com.wangwei.myreflec1;


public class Demo1 {

    /*
    获取class对象的三种方式
    1.Class.forName("全限定类名")
    2.类名.class
    3.对象.getClass();
     */

    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.wangwei.myreflec1.Student");
        System.out.println(aClass);

        Class<Student> aClass1 = Student.class;
        System.out.println(aClass1);

        Student student = new Student();
        Class<? extends Student> aClass2 = student.getClass();
        System.out.println(aClass==aClass1);
        System.out.println(aClass1==aClass2);

    }
}

运行结果

2.2利用反射获取构造方法

示例代码

Student类

java 复制代码
package com.wangwei.myreflect2;


public class Student {
    public Student(){

    }

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

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

    private String name;

    private int age;

    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;
    }
}

Demo2类

java 复制代码
package com.wangwei.myreflect2;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 通过反射获取构造方法
 */
public class Demo2 {

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

        //1.获取class字节码文件对象
        Class<?> aClass = Class.forName("com.wangwei.myreflect2.Student");

        //2.获取构造方法
//        Constructor<?>[] constructors = aClass.getConstructors();
//        for (Constructor con:constructors){
//            System.out.println(con);
//        }

//        Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
//        for (Constructor con:declaredConstructors){
//            System.out.println(con);
//        }

//        Constructor<?> constructor = aClass.getConstructor();
//        System.out.println(constructor);

        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(int.class);
        System.out.println(declaredConstructor);

        declaredConstructor.setAccessible(true);
        Student david = (Student)declaredConstructor.newInstance(18);
        System.out.println(david.getAge());


    }
}

运行结果

2.3利用反射获取成员变量

获取到成员变量,对成员变量进行赋值和取值操作。

示例代码

Student类

java 复制代码
package com.wangwei.myreflect3;


public class Student {
    public Student(){

    }

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

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

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

    private String name;

    private int age;

    public String gender;

    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 getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

Demo3类

java 复制代码
package com.wangwei.myreflect3;

import java.lang.reflect.Field;

/**
 * 通过反射获取成员变量
 */
public class Demo3 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //1.获取class字节码文件的对象
        Class<?> aClass = Class.forName("com.wangwei.myreflect3.Student");

        //2.获取公共成员变量
//        Field[] fields = aClass.getFields();
//        for(Field field:fields){
//            System.out.println(field);
//        }

        //获取所有成员变量
//        Field[] declaredFields = aClass.getDeclaredFields();
//        for(Field field:declaredFields){
//            System.out.println(field);
//        }

        //获取单个公共的成员变量
        Field gender = aClass.getField("gender");
        System.out.println(gender);

        //获取成员变量的值
        Student student = new Student("David", 18, "男");
        String value = (String)gender.get(student);
        System.out.println(value);

        //修改对象成员变量的值
        gender.set(student,"Daxi");
        String value1 = (String)gender.get(student);
        System.out.println(value1);

    }
}

运行结果

2.4利用反射获取成员方法


Student类

java 复制代码
package com.wangwei.myreflect4;


public class Student {

    public Student(){

    }

    public Student(String name,int age){

    }
    private String name;

    private int age;

    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 void sleep(){
        System.out.println("睡觉");
    }

    private void eat(String something){
        System.out.println("吃"+something);
    }
}

Demo4类

java 复制代码
package com.wangwei.myreflect4;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class Demo4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //1.获取class字节码文件对象
        Class<?> aClass = Class.forName("com.wangwei.myreflect4.Student");

        //2.获取所有公共的方法对象(包含父类中的方法)
//        Method[] methods = aClass.getMethods();
//        for (Method method:methods){
//            System.out.println(method);
//        }

        //获取所有的方法对象(不能回去父类的,但是可以获取本类中私有的方法
//        Method[] declaredMethods = aClass.getDeclaredMethods();
//        for (Method method:declaredMethods){
//            System.out.println(method);
//        }

        //获取具体方法对象
        Method eat = aClass.getDeclaredMethod("eat", String.class);
        System.out.println(eat);

        //方法运行
        Student student = new Student();
        eat.setAccessible(true);
        eat.invoke(student, "汉堡");
    }
}

运行结果

三、总结

  1. 在项目新架构中大量使用了反射,越发能够体会到反射的强大之处,是实现架构底层高复用、高扩展、高维护的实现方式之一。

四、升华

  1. 学习是一个迭代的过程:通过这一次的博客总结,博主对于反射的概念理解以及在宏观的运用上达到了熟练的层次。
相关推荐
秋野酱6 分钟前
基于javaweb的SpringBoot自习室预约系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
面试官E先生26 分钟前
【极兔快递Java社招】一面复盘|数据库+线程池+AQS+中间件面面俱到
java·面试
琢磨先生David31 分钟前
构建优雅对象的艺术:Java 建造者模式的架构解析与工程实践
java·设计模式·建造者模式
小雅痞1 小时前
[Java][Leetcode simple]26. 删除有序数组中的重复项
java·leetcode
青云交1 小时前
Java 大视界 -- 基于 Java 的大数据分布式存储在工业互联网海量设备数据长期存储中的应用优化(248)
java·大数据·工业互联网·分布式存储·冷热数据管理·hbase 优化·kudu 应用
纸包鱼最好吃1 小时前
java基础-package关键字、MVC、import关键字
java·开发语言·mvc
唐山柳林1 小时前
城市生命线综合管控系统解决方案-守护城市生命线安全
java·安全·servlet
PgSheep1 小时前
Spring Cloud Gateway 聚合 Swagger 文档:一站式API管理解决方案
java·开发语言
蒂法就是我2 小时前
详细说说Spring的IOC机制
java·后端·spring
程序员拂雨2 小时前
Java知识框架
java·开发语言