详解JAVA 反射机制

详解JAVA 反射机制

什么是反射机制

反射机制是 Java 语言提供的一种能力,它允许本来在编译期无法访问的类的内部信息,在程序运行期可以获取到。使用反射机制,我们可以在程序运行时动态地获取类型信息、构造对象、访问字段和方法等。

反射机制的应用场景

  1. 设计灵活,可扩展性好。比如很多插件式的框架,允许用户开发自定义的模块,但是这些模块编译时是不确定的,只有在程序运行时才能确定,这时候就需要反射机制。
  2. 工具类各种框架,例如 Spring,MyBatis 等。这些框架都是基于反射提供核心功能的。

反射机制的基本使用

Java 反射的基本操作都封装在 java.lang.reflect 包中。我们可以通过这个包提供的类来获取类的相关信息。

获取 Class 对象

获取 Class 对象的方法有三种:

  1. 使用getClass()方法:用于获取对象所属的类的 Class 对象。
public class ReflectionDemo {
    public static void main(String[] args) {
        String str = "Hello, Java";
        Class cls = str.getClass();
        System.out.println(cls.getName());
    }
}
  1. 使用 .class 方法:用于获取某个类的 Class 对象。
public class ReflectionDemo {
    public static void main(String[] args) {
        Class cls = String.class;
        System.out.println(cls.getName());
    }
}
  1. 使用 Class.forName() 方法:根据类的全限定名获取 Class 对象。
public class ReflectionDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        Class cls = Class.forName("java.lang.String");
        System.out.println(cls.getName());
    }
}

创建对象

获取了 Class 对象之后,我们可以通过它来创建对象。一般有两种方式:

  1. 使用 Class.newInstance() 方法(已过时)。
public class ReflectionDemo {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        Class cls = String.class;
        String str = (String) cls.newInstance();
        System.out.println(str);
    }
}
  1. 使用 Constructor.newInstance() 构造器方法。
public class ReflectionDemo {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = String.class;
        Constructor constructor = cls.getConstructor(String.class);
        String str = (String) constructor.newInstance("Hello, Java");
        System.out.println(str);
    }
}

访问属性

  1. 获取字段。
public class ReflectionDemo {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Person person = new Person();
        Class cls = person.getClass();
        Field field = cls.getDeclaredField("name");
        field.setAccessible(true);
        String name = (String) field.get(person);
        System.out.println(name);
    }
}

class Person {
    private String name = "Tom";
}
  1. 设置字段的值。
public class ReflectionDemo {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Person person = new Person();
        Class cls = person.getClass();
        Field field = cls.getDeclaredField("name");
        field.setAccessible(true);
        field.set(person, "Jerry");
        String name = (String) field.get(person);
        System.out.println(name);
    }
}

class Person {
    private String name = "Tom";
}

访问方法

  1. 获取方法。
public class ReflectionDemo {
    public static void main(String[] args) throws NoSuchMethodException {
        Person person = new Person();
        Class cls = person.getClass();
        Method method = cls.getDeclaredMethod("sayHello");
        method.setAccessible(true);
        method.invoke(person);
    }
}

class Person {
    private void sayHello() {
        System.out.println("Hello, Java");
    }
}
  1. 调用方法。
public class ReflectionDemo {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Person person = new Person();
        Class cls = person.getClass();
        Method method = cls.getDeclaredMethod("getAge");
        method.setAccessible(true);
        int age = (int) method.invoke(person);
        System.out.println(age);
    }
}

class Person {
    private int age = 18;

    private int getAge() {
        return age;
    }
}

示例1:通过反射获取类的信息

public class ReflectionDemo {
    public static void main(String[] args) {
        Class cls = String.class;

        // 获取类名
        System.out.println("类名:" + cls.getName());

        // 获取修饰符
        int modifiers = cls.getModifiers();
        System.out.println("修饰符:" + Modifier.toString(modifiers));

        // 获取父类名
        String superClassName = cls.getSuperclass().getName();
        System.out.println("父类名:" + superClassName);

        // 获取接口名
        Class[] interfaces = cls.getInterfaces();
        for (Class i : interfaces) {
            System.out.println("接口名:" + i.getName());
        }
    }
}

输出结果:

类名:java.lang.String
修饰符:public final
父类名:java.lang.Object

示例2:通过反射动态创建对象

public class ReflectionDemo {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        Class cls = String.class;
        String str = (String) cls.newInstance();
        System.out.println(str);
    }
}

输出结果:

Exception in thread "main" java.lang.InstantiationException: java.lang.String
    at java.lang.Class.newInstance(Class.java:427)

因为 String 类是不可变类,无法通过反射来修改其中的值,所以会抛出 InstantiationException 异常。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JAVA 反射机制 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 如何用idea数据库编写快递e站

    如何用IDEA数据库编写快递E站的完整攻略: 安装数据库和IDEA 首先需要安装数据库和IDEA,常用的数据库有MySQL和PostgreSQL。使用过程中也需要安装相应的驱动程序。如果你使用的是Maven或Gradle等构建工具,那么你可以在配置文件中添加相应的依赖项,自动下载驱动程序。 创建数据库和表格 在IDEA中连接到数据库服务器,创建一个新的数据库…

    Java 2023年5月20日
    00
  • Java字符串技巧之删除标点或最后字符的方法

    让我来详细讲解一下“Java字符串技巧之删除标点或最后字符的方法”的完整攻略。 1. 删除标点 1.1 方法一:使用正则表达式 首先,我们可以使用正则表达式来删除字符串中的所有标点符号。具体来说,可以使用replaceAll()方法和正则表达式\\p{Punct}来实现。 示例代码: String text = "This is a sample …

    Java 2023年5月20日
    00
  • 25基于java的在线考试系统

    一、项目简介 随着互联网迅速发展,人们的生活已经越来越离不开互联网,人们足不出户就可以工作、买卖、学习等。对于在校学生,通过网络教育不仅可以随时进行网络学习,也可以根据学习的情况自我检测,有利于学生高效、快捷地掌握所学的知识。本系统预设计的基于网络的学生自测系统将实现多种用户(包括学生、教师)同时访问,学生登录后可以针对课程的每一章节的每一道题目,提交答案;…

    Java 2023年5月6日
    00
  • CSS变量实现主题切换的方法

    下面我将详细讲解CSS变量实现主题切换的方法的完整攻略。 什么是CSS变量? CSS变量也称为自定义属性,是一种定义在CSS规则中的、可重复使用的值。与常规的CSS属性不同,CSS变量以双减号(–)开头,并可以在整个样式表的范围内使用。 实现简介 利用CSS变量实现主题切换的方法主要包括以下几个步骤: 定义多套主题色进行切换; 使用CSS变量将主题色应用到…

    Java 2023年6月15日
    00
  • 浅谈Java8新特性Predicate接口

    浅谈Java8新特性Predicate接口 Java 8中新增加了Predicate接口,它定义了一个输入参数和返回值都为Boolean的函数。这个接口定义了许多实用的方法,可以被用来组合复杂的布尔逻辑。 Predicate接口定义 Predicate接口有一个test方法,返回一个Boolean类型,其定义如下: @FunctionalInterface …

    Java 2023年5月26日
    00
  • java实现人员信息管理系统

    实现人员信息管理系统的完整攻略,可以分为如下几个步骤: 1.需求分析 首先需要明确人员信息管理系统需要实现的功能和需求。例如,需要实现的功能包括添加人员信息、查询人员信息、修改人员信息、删除人员信息等。 2.数据库设计 设计好人员信息管理系统所需的数据库结构,确定表格和字段。根据需求分析,表格可以分为人员信息表、部门信息表等。字段包括姓名、性别、年龄、电话、…

    Java 2023年5月23日
    00
  • Java有趣好玩的图形界面开发八个案例实现

    感谢您对Java图形界面开发的关注,关于Java有趣好玩的图形界面开发八个案例实现的攻略,下面给你一个详细的介绍。 八个案例 Java图形界面开发八个案例是由Java研究社推出的一门Java课程。该课程主要通过八个实例,让大家初步掌握Java图形界面的开发。这八个案例包括:电子时钟、文字跑马灯、图片浏览器、字母连线游戏、翻牌游戏、俄罗斯方块、英雄连连看、飞机…

    Java 2023年5月18日
    00
  • 详解SpringBoot+Thymeleaf 基于HTML5的现代模板引擎

    Sure,下面我会详细讲解“详解SpringBoot+Thymeleaf 基于HTML5的现代模板引擎”的完整攻略。 简介 Thymeleaf 是一个用于 Web 与独立环境的现代服务器端 Java 模板引擎。Thymeleaf 的主要目标是提供一种优雅和高度可维护的创建 XHTML / HTML5 的模板的方式;同时也可以非常轻松地拓展为JSP等模板引擎,…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部