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反射常用方法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 静态数据初始化的示例代码

    Java 静态数据初始化的示例代码

    这篇文章主要介绍了Java 静态数据初始化的示例代码,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-09-09
  • 深入剖析Java中的各种异常处理方式

    深入剖析Java中的各种异常处理方式

    这篇文章主要介绍了深入剖析Java中的各种异常处理方式,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-07-07
  • SpringBoot开发案例之配置Druid数据库连接池的示例

    SpringBoot开发案例之配置Druid数据库连接池的示例

    本篇文章主要介绍了SpringBoot开发案例之配置Druid数据库连接池的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-03-03
  • java基于控制台的学生学籍管理系统

    java基于控制台的学生学籍管理系统

    这篇文章主要为大家详细介绍了java基于控制台的学生学籍管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • Java concurrency之集合_动力节点Java学院整理

    Java concurrency之集合_动力节点Java学院整理

    Java集合主体内容包括Collection集合和Map类;而Collection集合又可以划分为List(队列)和Set(集合),有需要的小伙伴可以参考下
    2017-06-06
  • SpringBoot Redis缓存数据实现解析

    SpringBoot Redis缓存数据实现解析

    这篇文章主要介绍了SpringBoot Redis缓存数据实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Java线程阻塞工具LockSupport用法详解

    Java线程阻塞工具LockSupport用法详解

    Java中的LockSupport是一个用于线程同步的工具类,它提供了一种基于线程的阻塞和唤醒机制,LockSupport可以让线程在特定条件下阻塞挂起,等待其他线程发送信号来唤醒它,本文将通过一个小案例给大家介绍一下LockSupport怎么用,让你永远记住它
    2023-08-08
  • SpringMVC+MyBatis分页(最新)

    SpringMVC+MyBatis分页(最新)

    本篇文章主要介绍了SpringMVC+MyBatis分页,具有一定的参考价值,有兴趣的可以了解一下。
    2016-12-12
  • Java实现截图小工具的完整代码

    Java实现截图小工具的完整代码

    这篇文章主要介绍了Java实现截图小工具的完整代码,用Java的图形用户界面GUI技术写了一个电脑截图小工具,本程序代码简单,涉及到异常处理,事件处理,图形用户界面等,需要的朋友可以参考下
    2022-05-05
  • Java使用wait/notify实现线程间通信上篇

    Java使用wait/notify实现线程间通信上篇

    wait()和notify()是直接隶属于Object类,也就是说所有对象都拥有这一对方法,下面这篇文章主要给大家介绍了关于使用wait/notify实现线程间通信的相关资料,需要的朋友可以参考下
    2022-12-12

最新评论