java反射常用方法案例详解

 更新时间:2023年06月08日 12:05:21   作者:祁_z  
Java反射指的是一个机制,这种机制可以在Java程序运行时(动态)实例化对象、读写属性、调用方法,这篇文章主要介绍了java反射常用方法,需要的朋友可以参考下

1.反射概述

Java反射指的是一个机制,这种机制可以在Java程序运行时(动态)实例化对象、读写属性、调用方法。

关键词:运行时

一般在我们开发程序时,都知道自己具体用的什么类,直接创建即可。但是当写一些通用的功能时,就不能在编译时把具体类的类型写死,因为程序运行起来后可能会有多种类型的可能,此时就需要在运行时动态的去调用某个类的属性和方法,这就必须通过反射来实现。

案例:

// 不知道调用者传入什么类型对象。
public static String instance(Object obj)  {
	……
}

如何知道方法的参数Object是什么类型?

一般有两种做法:

第一种做法:是知道参数类型有哪几种情况,可以使用instanceof运算符进行判断,再利用强制类型转换将其转换成其运行时类型的变量即可。

  public static String getTypeInstanceof(Object obj){
        // 学生
        if (obj instanceof Student){
            Student student = (Student) obj;
            String userType = student.getUserType("王明");
            return userType;
        }
        // 老师
        if (obj instanceof Teacher){
            Teacher teacher = (Teacher) obj;
            String userType = teacher.getUserType("王明");
            return userType;
        }
        return null;
    }

 第二种做法:在编译时根本无法预知该对象和类可能属于哪些类,程序只依靠运行时信息动态的来发现该对象和类的真实信息,这就必须使用反射。

 public static String getType(Object obj) {
        // 通过反射获取运行时类
        Class<?> aClass = obj.getClass();
        try {
            // 实例化对象
            Object instance = aClass.newInstance();
            // 调用getUserType方法
            // 匹配对象中的getUserType()方法,参数类型为String
            Method method02 = aClass.getMethod("getUserType", String.class);
            // 调用匹配的方法,传入参数
            String invoke = (String) method02.invoke(instance, "王明");
            return invoke;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

 案例全部代码:

public class Demo1 {
    public static void main(String[] args) {
        // 测试Instanceof方式
        Teacher teacher = new Teacher();
        String typeInstanceof = getTypeInstanceof(teacher);
        System.out.println(typeInstanceof);
        // 测试反射方式
        Student student = new Student();
        String type = getType(student);
        System.out.println(type);
    }
    public static String getTypeInstanceof(Object obj){
        // 学生
        if (obj instanceof Student){
            Student student = (Student) obj;
            String userType = student.getUserType("王明");
            return userType;
        }
        // 老师
        if (obj instanceof Teacher){
            Teacher teacher = (Teacher) obj;
            String userType = teacher.getUserType("王明");
            return userType;
        }
        return null;
    }
    /**
     * 获取用户类型方法(老师、学生...)
     */
    public static String getType(Object obj) {
        // 通过反射获取运行时类
        Class<?> aClass = obj.getClass();
        try {
            // 实例化对象
            Object instance = aClass.newInstance();
            // 调用getUserType方法
            // 匹配对象中的getUserType()方法,参数类型为String
            Method method02 = aClass.getMethod("getUserType", String.class);
            // 调用匹配的方法,传入参数
            String invoke = (String) method02.invoke(instance, "王明");
            return invoke;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 学生类
     */
    static class Student {
        public String getUserType(String str) {
            System.out.println(str);
            return "学生-" + str;
        }
    }
    /**
     * 老师类
     */
    static class Teacher {
        public String getUserType(String str) {
            System.out.println(str);
            return "老师-" + str;
        }
    }
}

2. 反射获取Class对象的三种方式

通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象。

方式一:

Class.forName("包名.类名")   - 常用方式

例如:Class.forName("com.kexuekt.Student");

方式二:

使用类的class属性来获取该类对应的Class对象

例如: Student.class;

方式三:

调用对象的getClass()方法,该方法是Object类中的方法,因为每个类默认继承了Object类,所有的Java对象都可以调用该方法

例如:

Student stu = new Student();

stu.getClass();

3.反射常用方法

3.1反射获取构造方法

  • Constructor<?>[] getDeclaredConstructors​():获取所有构造方法
  • Constructor<?>[] getConstructors​():获取所有public构造方法
  • Constructor<T> getConstructor​():获取无参构造方法
  • Constructor<T> getDeclaredConstructor​(Class<?>... parameterTypes):根据参数类型获取有参构造方法
  • 创建实例化对象方法 T newInstance​(Object... initargs):根据指定的构造方法创建对象

 3.2反射获取成员变量

  • Field[] getDeclaredFields​():获取所有成员变量
  • Field getDeclaredField​(String name):获取单个成员变量
  • Field[] getFields​():获取所有public成员变量
  • Field getField​(String name):获取单个public成员变量
  • Field类中用于给成员变量赋值的方法void set​(Object obj, Object value):给obj对象的成员变量赋值为value

        私有成员变量设置值,需要取消访问权限检查 Field.setAccessible(true);

3.3反射获取成员方法

  • Method[] getMethods​():获取所有public成员方法,包括继承的
  • Method[] getDeclaredMethods​():获取所有成员方法,不包括继承的
  • Method getMethod​(String name, Class<?>... parameterTypes) :获取单个public成员方法
  • Method getDeclaredMethod​(String name, Class<?>... parameterTypes):获取单个成员方法
  • Method类中用于调用成员方法的方法Object invoke​(Object obj, Object... args):调用obj对象的成员方法,参数是args,返回值是Object类型

3.4反射获取构造、成员变量、成员方法Demo

学生类

class Student {
    private String name;
    public Integer age;
    public Student(){
    }
    public Student(String name, Integer age){
        this.name = name;
        this.age = age;
    }
    private String getUserType(String str) {
        System.out.println(str);
        return "学生-" + str;
    }
    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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

获取构造方法Demo

获取无参构造方法 

Class aClass = Student.class;
Constructor constructor = aClass.getConstructor();
Student newInstance = (Student)constructor.newInstance();

 根据参数类型获取有参构造方法

// 根据参数类型获取构造方法
Class aClass = Student.class;
Class<?>[] classes = {Class.forName("java.lang.String"), Class.forName("java.lang.Integer")};
Constructor c = aClass.getDeclaredConstructor(classes);
Student student = (Student)c.newInstance("王明", 1);
System.out.println(student.toString());

获取成员变量方法 

获取所有成员变量方法

Class aClass = Student.class;
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
    System.out.println(field.getName());
}

获取指定成员变量方法

Class aClass = Student.class;
Field name = aClass.getDeclaredField("name");

给private、public成员变量赋值

// 获取name私有成员变量
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
// 获取age成员变量
Field age = aClass.getDeclaredField("age");
// 通过反射实例化对象
Student student = aClass.getConstructor().newInstance();
// 成员变量参数赋值
name.set(student, "王明");
age.set(student, 20);
System.out.println(student.toString());

获取成员方法

获取本类中所有成员方法

Class aClass = Student.class;
Method[] methods = aClass.getDeclaredMethods();
for (Method method : methods) {
    System.out.println(method.getName());
}

调用成员方法

// 获取私有成员方法
Method getUserType = aClass.getDeclaredMethod("getUserType", Class.forName("java.lang.String"));
// 关闭权限检查
getUserType.setAccessible(true);
// 实例化对象
Student student = aClass.getConstructor().newInstance();
// 调用方法,传入参数
Object invoke = getUserType.invoke(student, "王亮");
System.out.println(invoke);

到此这篇关于java反射常用方法的文章就介绍到这了,更多相关java反射常用方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot中随机盐值+双重SHA256加密实战

    SpringBoot中随机盐值+双重SHA256加密实战

    本文主要介绍了SpringBoot中随机盐值+双重SHA256加密实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • java基于双向环形链表解决丢手帕问题的方法示例

    java基于双向环形链表解决丢手帕问题的方法示例

    这篇文章主要介绍了java基于双向环形链表解决丢手帕问题的方法,简单描述了丢手帕问题,并结合实例形式给出了Java基于双向环形链表解决丢手帕问题的步骤与相关操作技巧,需要的朋友可以参考下
    2017-11-11
  • java无锁hashmap原理与实现详解

    java无锁hashmap原理与实现详解

    本文主要介绍了java无锁hashmap原理与实现,大家参考使用吧
    2014-01-01
  • SpringBoot实现异步事件Event详解

    SpringBoot实现异步事件Event详解

    这篇文章主要介绍了SpringBoot实现异步事件Event详解,异步事件的模式,通常将一些非主要的业务放在监听器中执行,因为监听器中存在失败的风险,所以使用的时候需要注意,需要的朋友可以参考下
    2023-11-11
  • 基于Springboot实现JWT认证的示例代码

    基于Springboot实现JWT认证的示例代码

    本文主要介绍了基于Springboot实现JWT认证,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Springboot Shiro anno不启作用问题及解决

    Springboot Shiro anno不启作用问题及解决

    在Shiro配置中遇到静态资源被拦截的问题,通过排除LinkedHashMap过滤次序和将过滤器手动创建而不是注册到容器中解决,同时,确保JwtUtil类也不注册到容器中,以避免请求报Not authorized错误
    2026-03-03
  • Java启动参数从基础配置到高级调优(最新整理)

    Java启动参数从基础配置到高级调优(最新整理)

    文章系统讲解Java启动参数分类、内存管理配置、GC调优策略及生产环境实践,重点涵盖标准/非标准参数、堆/元空间/直接内存设置、G1/Parallel等回收器选择,并提供压缩指针、容器化部署等优化建议,感兴趣的朋友跟随小编一起看看吧
    2025-08-08
  • Spring Boot 整合 Apache Dubbo的示例代码

    Spring Boot 整合 Apache Dubbo的示例代码

    Apache Dubbo是一款高性能、轻量级的开源 Java RPC 框架,这篇文章主要介绍了Spring Boot 整合 Apache Dubbo的方法,本文通过示例说明给大家讲解的非常详细,需要的朋友可以参考下
    2021-07-07
  • Java中replace与replaceAll的区别与测试

    Java中replace与replaceAll的区别与测试

    replace和replaceAll是JAVA中常用的替换字符的方法,下面这篇文章主要给大家介绍了关于Java中replace与replaceAll的区别与测试,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • Java中ArrayList集合的遍历方式的多种方法

    Java中ArrayList集合的遍历方式的多种方法

    本文主要介绍了Java中ArrayList集合的遍历方式的多种方法,包括普通for循环、增强for循环、迭代器、ListIterator、Stream API和并行流,具有一定的参考价值,感兴趣的可以了解一下
    2025-05-05

最新评论