Java之反射

Java之反射

目录

反射

定义

主要用途

反射相关的类

Class类中【获得类相关方法】

Class类中【获得类中属性相关的方法】

Class类中【获得类中注解相关的方法】

Class类中【获得类中构造器相关的方法】

Class类中【获得类中方法相关的方法】

获得Class对象

代码示例1

代码示例2

反射的优缺点


反射
定义

Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制。

主要用途

1.动态地创建类的实例:在运行时根据类的全限定名创建对象。
2.检查类的结构:获取类的成员变量、方法、构造器等信息。
3.调用方法:在运行时动态地调用对象的方法。
4.访问和修改私有字段:即使在类定义中字段是私有的,也可以通过反射来访问和修改。

反射相关的类
类名 用途
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Filed类 代表类的成员变量/类的属性
Method类 代表类的方法
Constructor类 代表类的构造方法

Class类

Class类代表类的实体,在运行的Java应用程序中表示类和接口 .

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为一个对象,这个对象就是java.lang.Class,这样当程序在运行时,每个.class文件就最终变成了Class类对象的一个实例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类。

Class类中【获得类相关方法】
方法 用途
getClassLoader() 获得类的加载器
getDeclaredClasses() 返回一个数组,数组中包含该类的所有类和和接口类的对象(包括私有的)
forName(String className) 根据类名返回类的对象
newInstance() 创建类的实例
getName() 获得类的完整路径名字
Class类中【获得类中属性相关的方法】
方法 用途
getField(String name) 获得某个公有的属性对象
getFields() 获得所有公有的属性对象
getDeclaredField(String name) 获得某个属性对象
getDeclaredFields() 获得所有属性对象
Class类中【获得类中注解相关的方法】
方法 用途
getAnnotation(Class annotationClass) 返回该类中与参数匹配的公有注解对象
getAnnotations() 返回该类中所有的公有注解对象
getDeclaredAnnotaion(Class annotationClass) 返回该类中与参数类型匹配的所有注解对象
getDeclaredAnnotations() 返回该类所有的注解对象
Class类中【获得类中构造器相关的方法】
方法 用途
getConstructor(Class... parameterTypes) 获得该类中与参数类型匹配的公有构造方法
getConstructors() 获得该类的所有公有构造方法
getDeclaredConstructor(Class... parameterTypes) 获得该类中与参数类型匹配的构造方法
getDeclaredConstructors() 获得该类所有构造方法
Class类中【获得类中方法相关的方法】
方法 用途
getMethod(String name,Class... parameterTypes) 获得该类某个公有的方法
geMethods() 获得该类所有公有的方法
getDeclaredMethod(String name,Class... parameterTypes) 获得该类某个方法
getDeclaredMethds() 获得该类所有方法
获得Class对象

反射的第一步是获取代表某个类的Class对象。可以通过多种方式获取Class对象,最常见的是:

1.使用Class.forName(String className)静态方法,如果类名在类的路径中,则通过该类的全限定名(包括包名)来获取Class对象。注意,这种方式会抛出ClassNotFoundException。
2.使用.class语法,在编译时就已经确定。
3.调用对象的getClass()方法,在运行时确定对象的实际类型。

代码示例1
```java
class Student{
    //私有属性name
    private String name = "bit";
    //公有属性age
    public int age = 18;
    //不带参数的构造方法
    public Student(){
        System.out.println("Student()");
    }

    private Student(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }

    private void eat(){
        System.out.println("i am eat");
    }

    public void sleep(){
        System.out.println("i am pig");
    }

    private void function(String str) {
        System.out.println(str);
    }

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


public class Test {

    //Class对象 只有一个
    public static void main(String[] args) {
        Class c1;
        try {
            c1 = Class.forName("reflectdemo.Student");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

        Class c2;
        c2 = Student.class;


        Student student = new Student();
        Class c3 = student.getClass();

        System.out.println(c1.equals(c2));
        System.out.println(c1.equals(c3));
        System.out.println(c3.equals(c2));
    }
}

```
代码示例2
```java
class Student{
    //私有属性name
    private String name = "bit";
    //公有属性age
    public int age = 18;
    //不带参数的构造方法
    public Student(){
        System.out.println("Student()");
    }

    private Student(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }

    private void eat(){
        System.out.println("i am eat");
    }

    public void sleep(){
        System.out.println("i am pig");
    }

    private void function(String str) {
        System.out.println(str);
    }

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



public class ReflectDemo {
    //如何通过反射 实例化对象
    public static void reflectNewInstance() {
        Class c1;
        try {

            c1 = Class.forName("reflectdemo.Student");
            Student student = (Student) c1.newInstance();
            System.out.println(student);

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 反射私有的构造方法  屏蔽内容为获得公有的构造方法
    public static void reflectPrivateConstructor() {
        Class c1;
        try {
            c1 = Class.forName("reflectdemo.Student");

            Constructor con =
                    (Constructor)c1.getDeclaredConstructor(String.class,int.class);

            con.setAccessible(true);

            Student student = con.newInstance("zhangsan",18);

            System.out.println(student);

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 反射私有属性
    public static void reflectPrivateField() {
        Class c1;
        try {
            c1 = Class.forName("reflectdemo.Student");
            Field field = c1.getDeclaredField("name");
            field.setAccessible(true);

            Student student = (Student) c1.newInstance();

            field.set(student,"wangwu");

            System.out.println(student);

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 反射私有方法
    public static void reflectPrivateMethod() {
        Class c1;
        try {
            c1 = Class.forName("reflectdemo.Student");
            Method method = c1.getDeclaredMethod("function",String.class);

            method.setAccessible(true);

            Student student = (Student) c1.newInstance();

            method.invoke(student,"我是一个参数");

            //System.out.println(student);

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        //reflectNewInstance();
        //reflectPrivateConstructor();
        //reflectPrivateField();
        reflectPrivateMethod();
    }
}
```
反射的优缺点

优点

1. 对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法。

2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力。
3. 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

缺点

1.反射会破坏封装性,使代码难以理解和维护。
2.反射通常比直接代码调用慢,因为它涉及到类型检查等动态解析。
3.滥用反射可能导致安全问题,如访问或修改不应该被访问的私有成员。

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/4723.html

(0)
LomuLomu
上一篇 2024 年 12 月 28 日 下午2:31
下一篇 2024 年 12 月 28 日 下午3:32

相关推荐

  • Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

    探索Java Swing的奇妙世界 目录概览 引言 核心理念 组件与容器的奥秘 GridLayout(网格布局) GridBagLayout(网格包布局) FlowLayout(流式布局) BorderLayout(边框布局) BoxLayout(箱式布局) 事件监听的艺术 引言 核心理念 Java Swing 的架构精髓 Java Swing,这个为Jav…

    2024 年 12 月 28 日
    33500
  • 2025年蓝桥杯Java B组赛题深度剖析与解题策略

    作为一名连续两年参与蓝桥杯软件类Java B组竞赛的选手,我深刻体会到这项赛事对参赛者算法功底和临场应变能力的全面考验。今年的题目延续了蓝桥杯”夯实基础、鼓励创新”的命题风格,每道试题都像精心设计的思维迷宫,等待着选手用代码这把钥匙来开启。本文将系统梳理本届Java B组的典型赛题,通过全新的视角解析解题思路,分享编程实践中遇到的典型问题及其解决方案。这些内…

    未分类 2025 年 5 月 15 日
    12200
  • 华为OD机试E卷 –寻找符合要求的最长子串 –24年OD统一考试(Java & JS & Python & C & C++)

    文章目录 题目描述 输入描述 输出描述 用例 题目解析 JS算法源码 Java算法源码 python算法源码 c算法源码 c++算法源码 题目描述 给你一个字符串 s,字符串 s 首尾相连成一个环形,请你在环中找出 ‘l’、‘o’、‘x’ 字符都恰好出现了偶数次最长子字符串的长度。 输入描述 输入是一串小写的字母组成的字符串 输出描述 输出是一个整数 备注•…

    未分类 2025 年 1 月 12 日
    31800
  • Microi 吾码与 JavaScript:前端低代码平台的强大组合

    目录 一、引言 二、Microi 吾码概述 三、JavaScript 在 Microi 吾码前端开发中的应用 (一)前端 V8 引擎与 JavaScript (二)接口引擎与 JavaScript 四、JavaScript 在 Microi 吾码后端开发中的协同 (一)与 C# 后端框架的交互 (二)利用 gRPC 实现跨语言通信 五、Microi 吾码中 …

    2025 年 1 月 10 日
    29400
  • 从混沌到秩序:Python的依赖管理工具分析

    “`markdownPython的依赖管理工具尚未形成统一标准,其原因主要包括: 历史发展的随意性:Python在早期发展过程中,对于依赖管理的重视不足,缺乏从一开始就进行统一规划和设计的意识。 社区的分散性:Python社区庞大且分散,众多开发者和团队各自为政,根据自己的需求和偏好开发工具,缺乏统一的协调和整合机制。 多样化的使用场景:Python应用场…

    未分类 2024 年 12 月 26 日
    35900

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信