返回顶部
首页 > 资讯 > 后端开发 > Python >Java中的反射机制示例详解
  • 320
分享到

Java中的反射机制示例详解

2024-04-02 19:04:59 320人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录反射什么是Class类获取Class实例的三种方式通过反射创建类对象通过反射获取类属性、方法、构造器更改访问权限和实例赋值运用场景反射 反射就是把Java类中的各个成分映射成一个

反射

反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息及动态调用对象方法的功能叫Java的反射机制

每一个Java程序执行必须通过编译、加载、链接和初始化四个阶段

1.编译:将.java.文件编译成字节码.class文件

2.加载:查找并加载类的二进制数据

3.链接:

  • 验证:确保被加载类的正确性
  • 为类的静态变量分配内存,并将其初始化为默认值
  • 将类中的符号转换为直接引用

4.初始化:为类的静态变量赋予正确的初始值

什么是Class类

在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息

也就是说,无论你是什么对象,总会有有一个隐藏的Class对象与你相对应,而Class的实例表示正在运行的 Java 应用程序中的类和接口。借此,实现了我们Java的反射机制。

获取Class实例的三种方式

实例化对象调用getClass()方法

使用Class类的静态方法forName(),用类的名字获取一个Class实例

运用.class的方式来获取Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例

用代码来看一看:

public class reflect {

    public static void main(String[] args) throws ClassNotFoundException {

        Apple apple = new Apple();

        // 使用对象的getClass()方法
        Class a1 = apple.getClass();

        // 使用Class类的静态方法forName()
        Class a2 = Class.forName("p1.apple");

        // 运用.class的方式来获取Class实例
        Class a3 = Apple.class;

        System.out.printf("a1: %s\na2: %s\na3: %s", a1, a2, a3);

    }

}

class Apple {

    private Integer weight;

    private String color;
    
}

打印结果:

a1: class p1.apple
a2: class p1.apple
a3: class p1.apple
进程已结束,退出代码0

通过反射创建类对象

通过反射创建类对象主要有两种方式:通过 Class 对象的 newInstance() 方法、通过 Constructor 对象的 newInstance() 方法。

public class reflect {

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

        // 通过 Class 对象的 newInstance() 方法
        Class temp1 = Apple.class;
        Apple apple1 = (Apple) temp1.newInstance();
        
        // 通过 Constructor 对象的 newInstance() 方法
        Class temp2 = Apple.class;
        Constructor constructor1 = temp2.getConstructor();
        Apple apple2 = (Apple)constructor1.newInstance();

        // 通过 Constructor 对象创建类对象可以选择特定构造方法,而通过 Class 对象则只能使用默认的无参数构造方法。
        Class temp3 = Apple.class;
        Constructor constructor2 = temp3.getConstructor(Integer.class,String.class);
        Apple apple = (Apple)constructor2.newInstance(2, "Red");
        System.out.println(apple);

    }

}

class Apple {

    private Integer weight;

    private String color;

    // 无参构造器
    public Apple() {
        System.out.println("我是无参构造!");
    }

    // 有参构造器
    public Apple(Integer weight,String color) {
        this.weight = weight;
        this.color = color;
    }

    // 重写方法 方便打印显示对象内容
    @Override
    public String toString() {
        return "Apple{" +
                "weight=" + weight +
                ", color='" + color + '\'' +
                '}';
    }

}

打印结果:

我是无参构造!
我是无参构造!
Apple{weight=2, color='Red'}

进程已结束,退出代码0

通过反射获取类属性、方法、构造器

public class reflect {

    public static void main(String[] args) throws NoSuchFieldException {

        // 返回一个类中所有可访问的公共字段,包括该类的公共字段和其继承的类的公共字段
        Field[] fields1 = Apple.class.getFields();
        System.out.println("getFields结果");
        Arrays.stream(fields1).forEach(System.out::println);

        // 返回一个类中全部字段,但只包括该类的字段
        Field[] fields2 = Apple.class.getDeclaredFields();
        System.out.println("getDeclaredFields结果");
        Arrays.stream(fields2).forEach(System.out::println);

        // 根据字段名返回一个公开字段
        Field field1 = Apple.class.getField("noThing");
        System.out.println("getField结果");
        System.out.println(field1);

        // 根据字段名返回一个字段
        Field field2 = Apple.class.getDeclaredField("color");
        System.out.println("getDeclaredField结果");
        System.out.println(field2);

        // 同Field Method也有四种获取方式
        // 这里举其中一个例子
        Method[] methods = Apple.class.getDeclaredMethods();
        System.out.println("getDeclaredMethods结果");
        Arrays.stream(methods).forEach(System.out::println);

        // 同上 举一个获取构造器的例子
        Constructor[] constructors = Apple.class.getDeclaredConstructors();
        System.out.println("getDeclaredConstructors结果");
        Arrays.stream(constructors).forEach(System.out::println);

    }

}

class Apple {

    private Integer weight;

    private String color;

    public String noThing;

    public Apple() {

    }

    public Apple(Integer weight, String color) {
        this.weight = weight;
        this.color = color;
    }

    @Override
    public String toString() {
        return "Apple{" +
                "weight=" + weight +
                ", color='" + color + '\'' +
                '}';
    }

}

打印结果:

getFields结果
public java.lang.String p1.Apple.noThing
getDeclaredFields结果
private java.lang.Integer p1.Apple.weight
private java.lang.String p1.Apple.color
public java.lang.String p1.Apple.noThing
getField结果
public java.lang.String p1.Apple.noThing
getDeclaredField结果
private java.lang.String p1.Apple.color
getDeclaredMethods结果
public java.lang.String p1.Apple.toString()
getDeclaredConstructors结果
public p1.Apple()
public p1.Apple(java.lang.Integer,java.lang.String)

更改访问权限和实例赋值

首先,通过field.setAccessible()可更改属性的访问权限

public class reflect {

    public static void main(String[] args) throws NoSuchFieldException {

        // 实例化一个Apple
        Apple apple = new Apple();

        // 获取所有字段 并统一设定为公有属性
        Field[] fields = Apple.class.getDeclaredFields();
        Arrays.stream(fields).forEach( field -> {
            field.setAccessible(true);
            // 打印结果
            System.out.println(field);
            try {
                if (field.getType() == Integer.class) {
                    field.set(apple, 5);
                } else if (field.getType() == String.class) {
                    field.set(apple, "Red");
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        });
        // 查看apple结果
        System.out.println(apple);
      
    }

}

class Apple {

    private Integer weight;

    private String color;

    @Override
    public String toString() {
        return "Apple{" +
                "weight=" + weight +
                ", color='" + color + '\'' +
                '}';
    }

}

打印结果:

private java.lang.Integer p1.Apple.weight
private java.lang.String p1.Apple.color
Apple{weight=5, color='Red'}

进程已结束,退出代码0

通过源码文档和打印结果,可见setAccessable()方法并没有改变类字段的访问权限,而是作为一个标志,使得我们反射获取实例过程中可以对其进行操作

运用场景

在我看来,反射机制实际上就是上帝模式,如果说方法的调用是 Java 正确的打开方式,那反射机制就是上帝偷偷开的后门,只要存在对应的class,一切都能够被调用。

众所周知,语言有静态语言和动态语言两大分类,静态语言例如C/C++、Java、C#等,动态语言有pythonPHPjavascript等。为了让Java语言也有动态语言的特性,有了反射机制,解耦以及提高代码的灵活性。

反射在开发过中或许并不常见,可我们使用的框架工具底层都有反射的存在。动态代理设计模式、JDBC 的数据库的连接、spring 框架的使用等都应用到了反射机制。

以上就是Java中的反射机制示例详解的详细内容,更多关于Java反射机制的资料请关注编程网其它相关文章!

--结束END--

本文标题: Java中的反射机制示例详解

本文链接: https://lsjlt.com/news/141907.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java中的反射机制示例详解
    目录反射什么是Class类获取Class实例的三种方式通过反射创建类对象通过反射获取类属性、方法、构造器更改访问权限和实例赋值运用场景反射 反射就是把Java类中的各个成分映射成一个...
    99+
    2024-04-02
  • Java 反射机制的实例详解
    Java 反射机制的实例详解前言 今天介绍下Java的反射机制,以前我们获取一个类的实例都是使用new一个实例出来。那样太low了,今天跟我一起来学习学习一种更加高大上的方式来实现。正文 Java反射机制定义Java反射机制是指在运行状态中...
    99+
    2023-05-31
    java 反射机制 ava
  • Java中的反射机制详解
    目录一、什么是反射?二、为什么要用反射三、Class类四、获取Class类对象的四种方式五.通过反射构造一个类的实例①使用Class.newInstance②通过反射先获取构造方法再...
    99+
    2024-04-02
  • Java基础篇之反射机制示例详解
    目录一、什么是反射:二、反射的原理:三、反射的优缺点:四、反射的用途:五、反射机制常用的类:六、反射的基本使用:1、获得Class:主要有三种方法:2、判断是否为某个类的示例:3、创...
    99+
    2024-04-02
  • Java 反射机制详解及实例
    Java 反射机制详解及实例反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧!      &n...
    99+
    2023-05-31
    java 反射机制 ava
  • Java反射机制详解
    目录类的声明周期不同阶段都可以获取类对象获取Class类对象的方式的场景class类对象的功能如何获取私有变量的值根据有无主方法判断进程和线程反射出现的背景(记住)反射出现的背景类的...
    99+
    2024-04-02
  • java反射机制最详解
    目录java反射机制什么是反射?反射的功能:反射常用类:1.Class枚举类2.Constructor构造器3.Method方法类4.Field变量类反射运行指示图通过反射获取对象总结java反射机制 什么是反射? 在java开发中有一个...
    99+
    2020-08-07
    java java反射机制
  • Java-反射机制(超详解)
    Java反射机制概述 前言一、Java反射机制概述1. Java Reflection2. 动态语言 vs 静态语言 二、 Class类的理解1. 类的加载过程1.1 初步了解1.2 类的加载过程图解1.3 了解:什么时候会发...
    99+
    2023-08-17
    java 开发语言
  • Java反射机制基础详解
    目录1、什么是Java反射机制?2、反射机制原理3、Class类介绍3.1、Class类基本介绍3.2、Class类对象的获取方法Class.forname()3.3、可以获取Cla...
    99+
    2024-04-02
  • Java中反射机制和作用详解
    前言 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象。 那么接下来大师就带你们了解一下反射是什么,为什么...
    99+
    2024-04-02
  • PHP中反射机制的示例分析
    小编给大家分享一下PHP中反射机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!PHP的反射机制提供了一套反射API,用来访问和使用类、方法、属性、参数...
    99+
    2023-06-15
  • Java中的反射机制基本运用详解
    目录Java中的反射机制基本运用1、什么是反射(reflect)2、反射机制提供的功能3、反射->获取类对象4、反射->利用无参构造实例化对象5、反射->利用有参构...
    99+
    2024-04-02
  • Java反射机制中动态代理的示例分析
    这篇文章主要介绍了Java反射机制中动态代理的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1. 代理模式代理模式就是为其他对象提供一种代理来控制对这个对象的访问。其...
    99+
    2023-06-17
  • Python中的单例模式与反射机制详解
    目录单例模式反射hasattergetattrsetattr总结 单例模式 一般情况下,类可以生成任意个实例,而单例模式只生成一个实例 我们先用单例模式设计一个Rectangle类 ...
    99+
    2024-04-02
  • 详解Java中的反射机制和动态代理
    目录一、反射概述二、反射之Class类2.1、初识Class类2.2、Class有下面的几个特点2.3、获取Class类实例2.4、关于包装类的静态属性2.5、通过Class类的其他...
    99+
    2024-04-02
  • Java反射机制在Spring IOC中的应用详解
    目录Java反射机制在SpringIOC的应用下面是Spring通过配置进行实例化对象Spring的配置如下所示实现一下Spring底层处理原理反射机制、反射机制的作用、反射机制的功...
    99+
    2024-04-02
  • Java 反射机制
    简介: Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个...
    99+
    2024-04-02
  • 详解java中反射机制(含数组参数)
    详解java中反射机制(含数组参数)java的反射是我一直非常喜欢的地方,因为有了这个,可以让程序的灵活性大大的增加,同时通用性也提高了很多。反射原理什么的,我就不想做过大介绍了,网上一搜,就一大把。(下面我是只附录介绍下)Reflecti...
    99+
    2023-05-31
    java 反射机制 ava
  • Java基础篇之反射机制详解
    目录1、反射概述1.1什么是反射1.2、反射能干什么2、解剖类2.1反射构造方法2.1.1反射无参的构造函数2.1.2反射“一个参数”的构造函数2.1.3反射...
    99+
    2024-04-02
  • Java反射机制的实例分析
    这篇文章将为大家详细讲解有关Java反射机制的实例分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。在 Java 运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法对于任意一个对象...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作