【Java】反射

Java反射 Java的反射(reflection)机制是指在程序的运行状态中,借助取得任何类的内部信息,可以动态地构造任意一个类的对象,并能直接操作任意对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。反射主要用到java.lang.Class类和包下的一些类,是 Java 反射机制的核心包,提供了操作类及其成员(字段、方法、构造函数等)的类和接口。表示类的对象。提供了获取类的字段、方法、构造函数等方法。 阅读详情

激♂情互射,不如来个反射

0. 前言

反射无处不在:我们通过光的反射可以看到镜子里的自己;我们的反射弧反射可以产生应激反应;我们发动“圣防护罩”可以将攻击反射给对面…

在这里插入图片描述

而在面向对象中,反射是一种可以在运行时通过对象获取类,或者直接获取类对象的动态获取对象信息,动态调用对象方法的机制。是动态语言的关键。

众所周知,我们常用的Web框架就大量运用了反射机制,例如Spring。学习反射,是为日后学习框架原理打下基础。

不仅仅是Java,反射在其他支持面向对象的语言中也适用,例如C#、Python等。

参考教程

腾讯云社区-深度解析反射机制:https://cloud.tencent.com/developer/article/1416743

腾讯云社区-浩说编程优秀参考文章:https://cloud.tencent.com/developer/article/1862884

优快云-注解原理优秀参考文章:https://blog.youkuaiyun.com/nanhuaibeian/article/details/121290597

1. 反射

1.1 反射机制

反射机制允许程序在运行时检查、访问和修改自身的结构和行为。简单来说,它使得程序能够“自我观察”并对自身进行操作。使用反射,你可以动态地获取类的信息,如属性、方法和构造函数,并且可以在运行时创建、调用和修改它们。这种灵活性使得你可以在不事先知道类的具体细节的情况下,对其进行操作和扩展。

反射机制的概念读起来有点拗口,由于平时工作,若不是专门从事架构设计的工作,直接使用的场景可能会略少,因此我们需要多加练习,在练习的过程中主键理解。能较为顺利读懂框架的源码,吸收框架的设计思想,是我们的后期目标之一。

1.2 反射获取类对象

类对象是描述类的对象,描述该类有什么属性、方法,即类本身的对象。
一个ClassLoader下,一种类,只会有一个类对象存在。通常一个JVM下,只会有一个ClassLoader。

新建测试用类

public class Animal {
    public static final String TAG = "Animal";
    
    static {
        System.out.println("Animal static block");
        System.out.println(TAG);
    }

    private String name;

    public Animal() {
        this.name = "Animal";
    }

    public Animal(String name) {
        this.name = name;
    }

    public void eat() {
        System.out.println("Animal eat");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

上述测试类我添加了普通属性、方法也添加了一个静态属性、块,用来验证当我们获取类对象时,同时类属性也会实例化、静态块也会被执行,且仅执行一次。

获取类对象

public static void main(String[] args) {
        // get Animal class object
        // using try catch to avoid exception
        try {
            // 1. using Class.forName() method
            Class<?> animalClass = Class.forName("class19.Animal");
            // 2. using Class.class method
            Class<Animal> animalClass1 = Animal.class;
            // 3. using Object.getClass() method
            Class<? extends Animal> aClass = new Animal().getClass();
            System.out.println(animalClass==animalClass1);
            System.out.println(animalClass==aClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

上述 Demo 提供了3种方式给我们获取类对象:通过Class.forName()方法、通过类名.class、通过对象获取类对象。同时,通过执行结果,我们可以观察到:类属性只初始化了一次,类对象只有1个。

1.3 反射创建对象

通过反射创建对象,可以通过类对象获取构造器对象,再通过构造器对象创建一个对象:

public static void main(String[] args) {
        // test use reflect to create Animal object
        try {
            Class<Animal> animalClass = Animal.class;
            Constructor<Animal> constructor = animalClass.getConstructor();
            Animal animal = constructor.newInstance();
            System.out.println(animal.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

也可以通过类对象newInstance()方法获取:

public class TestReflectAnimal {
    public static void main(String[] args) {
        // test use reflect to create Animal object
        try {
            Class<Animal> animalClass1 = Animal.class;
            // create Animal object
            Animal animal = animalClass1.newInstance();
            System.out.println(animal.getName());
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

思考
当我们学会了通过类对象创建对象后,不难发现,我们只需要知道类名且项目里存在该类,我们就可以通过反射获取这些类的对象。我们观察一下我们平时做的项目,通过通过配置文件就可以对很多功能进行修改,这就是基于配置的思想,而底层通常都是反射实现配置文件影响实际对象的。

1.4 反射访问属性

反射获取属性通常有两个方法:

  • getDeclaredField :getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段
  • getField :getField 只能获取public的,包括从父类继承来的字段
public static void main(String[] args) {
        // using reflect to get or set attributes of Animal object
        Class<Animal> animalClass = Animal.class;
        try {
            Animal animal = animalClass.getConstructor().newInstance();
            Field nameField = animalClass.getDeclaredField("name");
            System.out.println(aniaml.getName());
            // 由于是 private
            nameField.setAccessible(true);
            nameField.set(animal, "Tom");
            System.out.println(animal.getName());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

1.5 反射调用方法

反射获取类对象后,可以通过getMethod方法调用方法:

public static void main(String[] args) {
        // using reflect to get or set methods of Animal object
        Class<Animal> animalClass = Animal.class;
        try {
            Animal animal = animalClass.getConstructor().newInstance();
            animal.eat();
            System.out.println(animal.getName());
            // using invoke to call method
            animalClass.getMethod("setName",String.class).invoke(animal, "Tom");
            System.out.println(animal.getName());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

2. 注解

注解是基于反射实现的,我们趁热打铁,把注解也撸一撸。

2.1 注解的概念

注解(Annotation)是一种元数据,它提供了对程序代码进行标记和补充信息的方式。注解可以应用于类、方法、字段等程序元素上,用于提供额外的描述和配置信息。

注解的原理是通过Java反射机制实现的。在编译阶段,注解会被编译器读取并处理,可以根据注解的定义来生成额外的代码或者进行其他特定的操作。在运行时,通过反射机制,我们可以获取到类、方法、字段等程序元素上的注解,并根据注解的信息来进行相应的处理。

2.2 元注解

元注解是用于注解其他注解的注解。Java中提供了一些内置的元注解,用于对自定义注解进行修饰和控制。

常见的元注解包括:

  • @Retention:指定注解的保留策略,有三个取值:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME。
  • @Target:指定注解的作用目标,可以是类、方法、字段等。
  • @Documented:指定注解是否生成在JavaDoc中。
  • @Inherited:指定注解是否具有继承性。

2.3 自定义注解

我们也可以自定义注解,用于对程序代码进行标记和补充信息。自定义注解需要使用@interface关键字来定义,注解中可以定义属性、方法等元素。

自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
    String value() default "";
    int count() default 0;
}

测试使用

@MyAnnotation(value = "Hello", count = 5)
public class MyClass {
    public void myMethod() {
        System.out.println("My Method");
    }
}

在上述代码中,我们定义了一个名为 MyAnnotation 的自定义注解。该注解具有两个属性:value 和 count,并且为它们设置了默认值。

然后,我们将 @MyAnnotation 注解应用到 MyClass 类上,并为注解的属性 value 设置为 “Hello”,count 设置为 5。

通过反射,我们可以获取 MyClass 类上的注解,并获取注解的属性值:

public static void main(String[] args) {
    Class<MyClass> myClass = MyClass.class;
    MyAnnotation annotation = myClass.getAnnotation(MyAnnotation.class);
    
    String value = annotation.value();
    int count = annotation.count();
    
    System.out.println("Value: " + value);
    System.out.println("Count: " + count);
}

3. 总结

本文介绍了反射机制以及如何使用反射来获取类对象、创建对象、访问属性和调用方法。反射是一种强大而灵活的机制,能够在运行时动态地操作类和对象。同时,本文还简单介绍了注解的概念、原理和自定义注解的方式。注解是一种标记和补充信息的机制,能够在编译阶段和运行时对程序进行特定处理。通过反射和注解的结合,我们可以实现更加灵活和可扩展的代码逻辑。反射是框架底层原理,注解是框架注解代替配置的灵活体现。但是实际学起来两者都是代码理解起来还好,但是概念略为拗口。由于篇幅关系,本文也暂未深入讲解更多的注解以及反射更贴近实际底层的模拟应用,我们应在日常工作学习中多留意,多阅读,多思考,渐渐拓展,慢慢消化。

期待未来的某一天,我能和各位大佬们一样,读源码就像读爽文,能立马理解,一目十行!

基于YOLOv8的包装商品智能检测系统完整指南—含论文、代码 《基于YOLOv8的包装商品智能检测系统》摘要: 本文提出了一套完整的零售商品自动检测解决方案,利用YOLOv8深度学习框架实现高精度、高效率的商品识别。系统针对SKU110K大规模商品数据集(含11,762张高密度货架图像)进行优化,包含数据预处理、模型训练、推理检测和可视化界面全流程。详细介绍了从CSV标注到YOLO格式的转换方法、环境配置指南及技术架构设计。该系统可应用于智能零售、物流仓储等多个场景,有效解决人工盘点效率低、误差大的痛点。实验表明,该系统具备毫秒级检测速度和批量处理能力,为商业数字化转 阅读详情

相关推荐

博途AI助手演示,完成简单且重复的梯形图代码,并导入到博途

自写个博途AI助手,下面演示AI帮我生成完善多个模拟量输入转换的代码,

gsjkwg的博客 1529

Java 反射

反射(reflection)是 Java 中的一项特性,它允许程序在运行时查询和操作类的信息。即,在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性。获取到方法和属性后,就可以对其进行修改。这种动态获取信息以及动态调用对象方法的功能也就是Java的反射机制

2301_76161469的博客 8777

逆向某团mtgsig参数时,我踩过的3个坑:从H5guard混淆到Python校验

本文详细解析了逆向某团mtgsig参数时遇到的三大挑战:H5guard混淆破解、环境补全检测与Python结果校验。通过实战案例,揭示了JavaScript加密算法的逆向技巧,包括控制流混淆拆解、隐蔽环境检测点规避以及跨语言校验的解决方案,为开发者提供了一套完整的逆向工程避坑指南。

weixin_27722377的博客 1065

Java之反射

1.什么是反射 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于 任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的 方法的功能称为java语言的反射机制。 2.Class类对象的三种实例化模式 在默认情况下我们是根据包名.类名找到类。而反射是根据对象来取得对象的信息来源。 要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所 以先要获取到每一个字节码文件对应的Clas....

柠檬精 4万+

Mission Planner连接Autopilot保姆级教程:从USB到无线全搞定

本文提供Mission Planner连接Autopilot的全面指南,涵盖USB直连、无线数传、蓝牙适配等多种连接方案。详细讲解驱动安装、波特率匹配、性能优化等关键步骤,并分享多链路冗余配置与故障转移的高阶技巧,助你快速解决连接问题。

weixin_28455801的博客 379

UCOS-III 系统移植

UCOSIII系统移植到GD32F303详细过程 工程代码:https://github.com/jslaobing/techIot_ucosiii_porting

TechIoT - 探索物联网与嵌入式系统 2087

java反射&python反射

作为一只主学java,次学python的猿,反射的梗,怎能不知道 一、反射是什么: 维基百科上给出的定义:在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为。 以我浅薄的编程思想理解的反射: 反射可以让我们在不打开程序文件的情况下,清楚的知道该程序的内部结构...

远处 1475

tkinter使用label视频播放

tkinter是python的界面开发包 使用tkinter显示视频流的一个办法是使用label来逐帧显示图片。 from Tkinter import * from PIL import ImageTk, Image import cv2 root = Tk() # Create a frame app = Frame(root, bg="white") app.grid() # Create a label in the frame lmian = Label(app) lmain.grid(

六十英里的专栏 5527

Java 反射体系

Java反射(Reflection)是Java语言的一个重要特性,它允许运行中的Java程序对自身进行检查,并且可以直接操作程序的内部属性。通过反射,我们可以在运行时获取类的信息、创建对象、调用方法以及访问和修改字段等。Java反射体系主要包括以下几个核心类:Class类:代表一个类或接口。每个类都有一个对应的Class对象,该对象包含了类的所有信息,如名称、父类、实现的接口、构造器、方法和字段等。可以通过以下几种方式获得Class类名.class对象.getClass()

weixin_47363690的博客 1512

别再乱点U盘里的.exe了!手把手教你彻底清除那个伪装成Usb Disk的蠕虫病毒

本文详细介绍了如何识别、清除和预防伪装成Usb Disk的蠕虫病毒。从识别感染迹象到安全备份文件,再到深度清理病毒残留和构建防护策略,提供了一套完整的U盘病毒解决方案。特别提醒用户注意U盘病毒的风险,并养成良好的使用习惯。

weixin_30496999的博客 675

【无标题】IP804A参考资料和管脚作用图

3.3V内置led控制内置EEPROM接口,用于哑应用ip804a,可集成为4X N端口PSE稳压器内置支持外部设备。多个系统和IC总线用于从每个IP804A收集PD电源状态,以支持全局电源管理。多个ip804a可以构建一个具有成本效益的PHY级PSE系统以支持PD分类和电源管理,而无需主机。基于LLDP(IEEE标准8023AT-2009的一部分),可以实时维护PSE和PD之间的动态电源管理,以提高电源效率。IP804A是一款用于POE(以太网供电)系统的4端口PSE(电源设备)控制器IC。

2301_78055735的博客 1059

Java 的反射

Java反射机制允许程序在运行时动态获取类信息并操作对象,是Java动态性的核心体现。反射通过Class类获取类结构,包括构造方法、字段和方法,还能创建对象、调用方法和修改字段值。反射支持泛型类型信息获取,广泛应用于框架开发、动态代理等场景。尽管反射功能强大,但性能开销较大,且可能破坏封装性,需谨慎使用。

weixin_73916358的博客 1252

[Dify实战] 招聘筛简历机器人:自动筛选、排序、生成面试要点-带绑定资源

摘要:本文介绍了如何利用Dify优化简历筛选流程,解决人工筛选耗时、标准不统一等问题。通过结构化输出"评分+亮点+风险+面试关注点",将主观判断转化为规则化流程。关键步骤包括:设计标准化Prompt、配置权重排序策略、确保公平合规性、与ATS系统对接,以及持续优化评估指标。该方法能显著提升筛选效率(缩短招聘周期)、增强一致性(避免主观偏差),并为面试官提供结构化参考信息,最终实现更高效精准的人才筛选。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 581

JAVA反射

Java是先编译再运行的语言,程序中对象的类型在编译期就确定下来了;而当程序在运行时需要动态加载某些类时(这些类因为之前用不到没有被加载到JVM),通过反射可以在运行时动态地创建对象并调用其属性,我们不需要提前在编译期知道运行的对象是谁。Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。Java反射机制的本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取t对象的各种信息。java反射详解。

qq_39239864的博客 959

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

java 反射_反射实例——JAVA反射机制

一、Java反射反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作...

weixin_39713578的博客 138

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

java反射三种方法_反射及暴力反射

作者:逯小逯出自:SegmentFault 思否原文:segmentfault.com/a/1190000037432381反射一、概述(1)反射的定位是很重要的,JVM和底层框架都离不开反射(2)反射的原理是拿到你的class文件里的数据,进行数据的操作(CURD)(3)反射提供了丰富的方法,来操作类里的各种数据(属性/方法/构造)(4)REflection(反射)是Java程序开发语言的特征之...

weixin_39586353的博客 2390

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java反射之方法反射demo

Java反射之方法反射demo package reflect; import java.lang.reflect.Method; public class ClassDemo3 { public static void main(String[] args) { String s = "hello"; ClassUtil.printClassMethodMessage(s

龙腾四海365的专栏 2693

Java反射概念及类的反射

Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接

wangliaizq10000的专栏 7390

Java 反射机制[Method反射]

Java 反射机制[Method反射] 接着上一篇Java 反射机制[Field反射],通过调用Person类的setName方法将obj的name字段的Value设置为"callPersonSetNameMethod"来了解什么是Method反射。示例代码很简单,很容易理解。 可以看到Method.invoke()实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.MethodAccessor来处理。 真正的反射是调用MethodAccessor.invoke

Stop Tears 1970

Java—反射

Java反射

且将&的博客 684

java反射

方法说明返回一个Method类型的数组其中包含 所有公共(public)方法。返回一个Method类型的数组其中包含 所有方法。>...返回一个公共的Method方法对象。>...返回一个方法Method对象。

qq_74947724的博客 955
上一篇: 【Java】Socket
下一篇: 【杂谈】浅浅地学学C语言指针
CoderSharry
博客等级 码龄4年 515粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值