Java的奇妙魔法,反射,超好玩,绝对值得收藏

Java反射:探索运行时的类奥秘 Java反射是指在运行时能够动态地获取一个类的所有信息,并能够操作类的属性和方法。在编译阶段,Java编译器会将Java源文件编译成字节码文件,而反射机制则允许我们在程序运行时,对这些字节码文件所代表的类进行进一步的探索和操作。通过反射,我们可以在运行时检查类的结构,实例化对象,调用方法,访问和修改字段的值等,而这些操作在编译时往往是无法确定的。Java反射机制是一项强大而又复杂的特性,它为开发者提供了在运行时动态操作类的能力,在众多的应用场景中都发挥着不可或缺的作用。 阅读详情

各位大侠们知道Java的反射是什么吗?可不是反着发射什么的哈。

反射是Java的一种机制,一般也叫做反射机制,本文会讲反射机制是什么和怎么使用。

请多多支持我的文章,之后会和大家分享更多优质内容。


先来看一段魔法吧

public class Test {
    private static void changeStrValue(String str, char[] value) {
    	// 只要执行魔法代码就可以达到下面的效果
        // 施展魔法的代码稍后揭秘
    }

    public static void main(String[] args) {
        changeStrValue("abc", new char[]{'d','e','f'});

        String abc = "abc";
        System.out.println("abc");
        System.out.println(abc);
        System.out.println("abc".equals(abc));
    }
}

进程结束,输出代码为0。


第一次看到这个执行结果一定会觉得很有意思。明明应该是"abc"怎么就变成了"def"呢?

反射机制是个什么玩意儿?

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

以上就是百科的解释。可能有点抽象,下面和大家通俗地解释一下。


构造任意一个类的对象

一般情况下,我们如果想要创建一个类的对象,应该要用到new关键字。但是像spring这样的框架,我们只需要配置类名,就可以得到类的实例。他是怎么做到的呢?

import java.util.List;

public class Test {
    /**
     * 根据类名取得类实例
     * @author 二当家的白帽子 https://le-yi.blog.youkuaiyun.com/
     * @param className
     * @param <T>
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    public static <T> T getInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Class<T> clazz = (Class<T>) Class.forName(className);
        return clazz.newInstance();
    }

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        List<String> list = getInstance("java.util.ArrayList");
        list.add("abc");
        list.add("def");

        for (String v : list) {
            System.out.println(v);
        }
    }
}

类名可以在程序运行中从配置文件获取,甚至是从网络获取,然后动态创建一个类的实例。


了解任意一个对象所属的类

import java.util.ArrayList;

public class Test {
     /**
     * 打印对象的类名
     * @author 二当家的白帽子 https://le-yi.blog.youkuaiyun.com/
     * @param o
     */
    public static void printClass(Object o) {
        System.out.printf(o.getClass().getName());
    }

    public static void main(String[] args) {
        printClass(new ArrayList<>());
    }
}

了解任意一个类的成员变量和方法

我们一般要使用一个类,先要知道有什么方法和属性,先了解,后使用。但是像spring那样的框架为什么可以为我们自动注入呢?他怎么知道我们一个对象里有什么属性呢?

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {
    /**
     * 打印类的属性
     * @author 二当家的白帽子 https://le-yi.blog.youkuaiyun.com/
     * @param clazz
     */
    public static void printFields(Class clazz) {
        System.out.println(clazz.getName() + "包含如下属性:");
        for (Field f : clazz.getDeclaredFields()) {
            System.out.println(f);
        }
    }

    /**
     * 打印类的方法
     * @author 二当家的白帽子 https://le-yi.blog.youkuaiyun.com/
     * @param clazz
     */
    public static void printMethods(Class clazz) {
        System.out.println(clazz.getName() + "包含如下方法:");
        for (Method m : clazz.getDeclaredMethods()) {
            System.out.println(m);
        }
    }

    public static void main(String[] args) {
        printFields(MyClass.class);
        printMethods(MyClass.class);
    }
}

class MyClass {
    private String name;

    public String getName() {
        return name;
    }

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

调用任意一个对象的属性和方法

像spring这样的框架,即使一个属性是私有属性并且没有set方法,一样可以注入。

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    /**
     * 调用一个对象的方法
     * @author 二当家的白帽子 https://le-yi.blog.youkuaiyun.com/
     * @param o
     * @param methodName
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static void callMethod(Object o, String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method m = o.getClass().getDeclaredMethod(methodName);
        m.setAccessible(true);
        m.invoke(o);
    }

    /**
     * 修改一个对象的属性
     * @author 二当家的白帽子 https://le-yi.blog.youkuaiyun.com/
     * @param o
     * @param fieldName
     * @param value
     * @throws IllegalAccessException
     */
    public static void changeFieldValue(Object o, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
        Field f = o.getClass().getDeclaredField(fieldName);
        f.setAccessible(true);
        f.set(o, value);
    }

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException {
        MyClass o = new MyClass();

        // 修改任意属性,即使是私有的
        changeFieldValue(o, "name", "二当家的白帽子");

        // 调用任意方法,即使是私有的
        callMethod(o, "printName");
    }
}

class MyClass {
	// 私有属性,只可以调用set方法修改
    private String name;

    private void printName() {
        // 私有方法,只有本类自己的实例可以调用
        System.out.println("My name is " + name);
    }

    public String getName() {
        return name;
    }

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

魔法揭秘

是时候揭秘魔法的真面目了,没错,也是利用了反射。

import java.lang.reflect.Field;

public class Test {
    /**
     * 修改字符串内部的值
     * @author 二当家的白帽子 https://le-yi.blog.youkuaiyun.com/
     * @param str
     * @param value
     */
    private static void changeStrValue(String str, char[] value) {
        try {
            Field f = str.getClass().getDeclaredField("value");
            f.setAccessible(true);
            f.set(str, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        changeStrValue("abc", new char[]{'d','e','f'});

        // 这里的"abc"字符串和上面调用changeStrValue的参数"abc"会指向同一块内存
        String abc = "abc";
        System.out.println("abc");
        System.out.println(abc);
        System.out.println("abc".equals(abc));
    }
}

要理解这段代码,除了反射机制还需要了解java对于字符串的处理。"字符串常量池"已经超出本文的范围,是另一个话题,本文就不多说了。

原本字符串内容是"abc",我们正常情况下无法修改这个内容,因为String是不变类。但是反射大法却可以打破一切禁忌。

结语

一般的程序可能用不到写反射的代码。但是像spring这样的框架,如果没有反射,我真的想不出如何实现呢。哪怕永远不需要用反射,了解机制对我们都有着莫大的好处。

如果感到有趣或者觉得文章对你有帮助还请多多给我三连,如果想要获得更多优质资源,可以加微信向我索取,暗号999获取80G超赞资源(大纲,基础梳理,拔高,面试,只有你想不到,没有我没整理。),我们之后再见。

林浩然与杨凌芸的Java魔法世界:一场关于反射、对象、属性和数组的奇妙冒险 在一个阳光明媚的编程日,我们的主角林浩然和杨凌芸决定探索Java世界中最神秘的角落——反射。在这个维度中,他们不仅能窥探类的秘密,还能操控万物的创造与变幻。 阅读详情

相关推荐

Java 的奇妙探险:揭秘 @Retention 和 @Target 的魔法奥秘

在 Java 的魔法世界中,@Retention 和 @Target 是注解的明星,它们分别负责注解的生存策略和适用范围。本文将揭示这对最佳拍档的奥秘,帮助你更好地掌握注解的魅力与应用。

专注于深入研究多种编程语言,以实战为导向,逐步拓展开发技能,提升工程化编码和思维能力,展现无敌技术实力。 446

java的上乘武功,反射,好好玩哦,绝对值得收藏

各位大侠们知道Java的反射是什么吗?可不是反着发射什么的哈

二当家的白帽子 1万+

Java魔法学院:3大绝技深度拆解反射机制,你真的会用吗?

经过一系列的学习,你已经掌握了Java反射机制的魔法。记住,反射虽然强大,但也需要谨慎使用。它可能会破坏封装性,影响性能,并可能引入安全漏洞。因此,在使用反射时,请确保你完全理解其后果。现在,拿起你的魔法杖,去创造属于你自己的魔法吧!记得,每一次实践都是学习的良机,而每一次失败都是通往成功的必经之路。愿你在Java的魔法世界里不断探索,成为一名真正的魔法师!

java专栏 508

十几年Java“老油条”,教你如何才能把Java学好学透彻。

一. 引子在说明Java该如何学习之前,威哥先带各位小伙伴来回顾一下Java语言的发展史。Java语言其实早在1982年,就已诞生于美国斯坦福大学的Sun公司,Sun的全称是「Stanford University Network」。Sun公司是一个充满活力、富于创造的硅谷公司。显然这样的公司都是很尊重员工的,老板会想尽可能的发挥出员工的创建力「榨取最大剩余价值」,最大程度上激发出员工的工作热情。时间来到1990年,Sun公司里有一个才华直往外噗噗冒的小伙子,他头秃了,但是他的确变强了。最近他心情不太好,因

威哥爱编程,华为 HDE,鸿蒙极客、优快云博客专家、《鸿蒙 HarmonyOS 5/6 开发之路》系列图书第一作者 1136

16种魔术方法

php 概念性知识,全面的魔术方法,不用再找,收藏直接看

小红书x-mini签名逆向实战:Frida动态Hook与算法还原

在移动App协议分析中,请求签名机制是保障接口安全的核心技术,其本质是客户端对请求参数、时间戳、设备指纹等要素进行加密认证的过程。理解签名原理需掌握Native层加密流程、JNI调用机制及密钥动态派生逻辑。Frida作为主流动态插桩工具,能绕过符号剥离、字符串加密和控制流混淆等反分析手段,在函数执行瞬间捕获寄存器状态、内存数据与调用上下文,实现签名算法的完整还原。该技术广泛应用于合规内容监测、API自动化调用与竞品协议研究等工程场景。本文聚焦小红书x-mini签名这一典型样本,详解从JNI_OnLoad定位

weixin_31264565的博客 457

Java 10大骚操作写法,亮瞎boss的双眼!

想不想学习装 B 式的 Java 骚操作花式写法? 没错,一文交会你! 1、集合初始化 集合的创建、赋值一步到位,想不想学? 来,上边跟我一起画个 List,在你下边画一个Map…… 哈哈,高大上的写法,栈长以前写过,写法虽然是很装X,然而并没有什么卵用。 2、算术 注意到上面size的写法没有? 明明可以写成: finalintsize=256; 他非要写成: finalintsize=-(-128)+127+1; 这么装 B 的写法...

Java0258的博客 3328

Unity UI Toolkit避坑指南:从官方Samples到实际项目,这些‘坑’我帮你踩过了

本文分享了Unity UI Toolkit在实际项目中的避坑经验和优化技巧,包括动画系统的高效替代方案、3D世界UI的创新实现方式、USS样式继承的反直觉规则等。通过详细的代码示例和性能优化策略,帮助开发者避免常见陷阱,提升开发效率。

weixin_29535577的博客 342

一些java语言的精巧写法

很简单的

lanxiaziyi的专栏 187

芯片详解——AD7606

AD7606详解

weixin_45661757的博客 5019

从零到一:使用阿里云百炼搭建企业级 AI Agent 完全实战手册(2026超详细版)

本文是一份企业级AI Agent构建手册,主要面向企业技术负责人、AI产品经理和后端开发工程师。手册详细介绍了如何在阿里云百炼平台上搭建企业智能体应用的全流程,包括环境准备、知识库构建、智能体创建、工具集成、工作流编排等核心环节。重点内容包括: 准备工作:阿里云账号注册、百炼服务开通、免费额度领取、API Key管理 知识库构建:文档格式要求、内容优化原则、RAG系统搭建 智能体开发:Agent创建、工具集成、复杂业务工作流设计 生产部署:多渠道接入、监控运维、安全治理 成本控制:Token预算管理、选型决

u010323587的专栏 1081

PHP中的魔术方法,转自:http://4nail.iteye.com/blog/604913

1.__construct() 当实例化一个对象的时候,这个对象的这个方法首先被调用。php代码class Test { function __construct() { echo "before"; } } $t = new Test();class Test { function __construct() { echo "before"; } } $t = new Test();输出是:st...

iteye_8029的博客 320

独立游戏开发者的新武器:实测腾讯混元3D自动绑骨,搭配Mixamo让角色动画制作效率翻倍

本文实测腾讯混元3D自动绑骨功能与Mixamo动画库的协同使用,显著提升独立游戏开发者的角色动画制作效率。通过解决卡通角色绑骨偏差、优化骨骼权重及动画状态机配置,使原本两周的流程缩短至三天,并分享Unity中的性能优化与版权合规要点。

weixin_42662605的博客 489

14.Java反射机制:解锁动态编程的魔法之门

Java反射机制为我们提供了强大的动态编程能力,它在很多实际应用场景中都发挥着关键作用。通过本文的介绍和示例代码,相信你对反射机制的原理和应用有了更深入的了解。当然,反射机制也有一定的性能开销,因为它是在运行时进行操作,所以在实际使用中,我们需要根据具体情况权衡利弊,合理地运用这一强大的工具。希望你能在今后的Java编程之旅中,灵活运用反射机制,创造出更加精彩的程序!

博客 841

基于Simulink与MATLAB的七轴OpenArm机械臂逆运动学仿真与轨迹规划完整指南

本文详细介绍了七自由度OpenArm机械臂在MATLAB/Simulink环境下的运动学仿真与轨迹规划实现方法。首先建立了机械臂的DH参数模型,验证了正运动学计算;随后提出了两种逆运动学求解算法(数值迭代法和臂型角参数化解析法)的MATLAB实现方案;最后在Simulink中搭建了完整的轨迹规划与控制系统。研究解决了七自由度冗余机械臂特有的多解性、奇异性和关节限位约束等核心问题,为OpenArm机械臂的运动控制提供了完整的技术方案和可运行代码实现。

AI的内部世界的博客 681

【异常】Milvus 向量数据库字段缺失错误分析与解决 MilvusVectorStoreServiceV2 - Failed to insert batch [0-1]: The field:

本文分析了Milvus向量数据库插入操作中出现的字段缺失错误。错误显示age_mode字段未提供,导致批量插入失败。根本原因是Milvus Schema要求所有定义字段必须存在,但代码中对部分字段采用条件添加方式。解决方案是将条件添加改为始终添加,为可能为null的字段提供空字符串默认值。文章总结了Schema约束、防御性编程等经验,并建议通过Schema变更检查、单元测试覆盖和数据校验层等预防措施避免类似问题。该问题影响product、mac、source等多个字段,修改后确保了数据插入的可靠性。

奶爸的编程之路,也就一周冷个三天 406

《Java世界的魔法标签:注解(Annotation)从使用到自定义的奇妙旅程》

Java注解(Annotation)就像是代码中的标签或咒语,本身没有功能,但告诉编译器、工具或框架如何处理被标记的代码。文章首先通过生活例子类比注解的作用,然后介绍JDK内置注解如@Override、@Deprecated等。接着讲解元注解如何定义自定义注解的适用范围和生命周期,并以创建@MyTest注解为例,演示如何通过反射在运行时解析注解实现特定功能,如自动执行测试方法。最后提及Spring框架中@Autowired等注解的实际应用,展示了注解在开发中的强大作用。整个内容生动形象地阐释了注解从使用到自

而世之奇伟、瑰怪,非常之观,常在于险远,而人之所罕至焉,故非有志者不能至也! 601

用一组可复现实验讲清 ABAP 内表 Standard / Sorted / Hashed 的性能差异

摘要(150字): SAP项目中性能问题常源于ABAP内表选型不当。标准表(STANDARD TABLE)写入快但查找慢(线性扫描),适合遍历场景;排序表(SORTED TABLE)保持有序,支持二分查找,适合范围查询;哈希表(HASHED TABLE)基于唯一键实现常数级查找,适合高频精确匹配。实验表明:标准表+BINARY SEARCH需预排序,成本可能高于直接使用排序表;哈希表在键匹配时性能最优。Gateway和RAP场景中,内表选型直接影响接口响应,建议根据读写负载(追加/遍历/精确查找)选择对应类

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 201

【你了解 Java 反射机制 吗?】

附赠好看电脑壁纸一张 反射

qq_44682003的博客 170

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

注解,反射在android View,Event中的奇妙实现

此博文产生的背景: 1.做android开发的都知道,在做项目时,用的最多的组件就是Activity,其实Activity就是对一系列View的封装,View就是最终展现UI的控件,所以在开发中基本上不可能不使用View,View既然是用户接口,那么用户作用在View上的一切动作,我们的程序必须对相应的操作做出相应的响应,在捕获事件,以及做处理之前我们必须完成两件事,1.获取该View的引用

Android 2054

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

深入浅出Java注解与反射:从原理到实战应用的艺术

在云原生、Serverless架构盛行的今天,注解与反射这对技术组合展现出更强大的生命力。它们不仅是框架开发的基石,更是实现灵活架构设计的核心工具。但开发者需要时刻铭记:能力越大,责任越大。合理运用这些元编程技术,在灵活性与可维护性之间找到最佳平衡点,才能编写出既强大又优雅的Java应用。‌思考题‌:如何设计一个基于注解的分布式事务框架?需要考虑哪些关键因素?本文通过理论解析、代码实战、性能优化等多维度剖析,构建了注解与反射的完整知识体系。

阿新的博客 973

java小故事_Java反射的小故事

Java反射的小故事:首先定义一个Java类1 packagecom.xiaoysec.test;23 public classPerson {4 privateString name;5 privateString sex;6 private intid;78 publicString getName() {9 returnname;10 }111...

weixin_42518930的博客 255

java反射调用main方法,private方法实现

最近研究jetty源代码的时候,发现这个容器里面的代码根本无法看懂,都是java语法,基本上都是反射+设计模式+配置文件。很莫名奇妙的方法调用。里面有调用main方法的反射,结果没看懂,所以就再来研究研究反射功能。由于反射的文章在网上太多了,我主要研究了一下main方法,private方法的调用。如下,反射调用HelloWorld类的方法。HelloWorld类如下: public class

重剑无锋 1994

《Java 世界的奇妙冒险》第三弹

在这个奇妙的 Java 世界里,注解、反射机制、序列化、内存模型、IO 流、并发编程和 JVM 各自扮演着重要的角色,它们相互协作,共同创造出一个丰富多彩、充满活力的代码世界。序列化就像是一个细心的打包员,它将小字符的状态和数据打包成一个个小包裹,以便于传输和保存。接下来,我们来到了反射机制的领域。为了让这个场景顺利进行,有许多并发工具和技术,如线程、锁和线程池等,它们帮助小字符们协调工作,避免冲突和死锁。JVM 就像是一个强大的守护天使,它负责将小字符们的代码转换成机器可以理解的指令,并进行优化和管理。

DC5621的博客 227

大话Java系列-真假美猴王,论动态代理与反射机制

真美猴王指出,假美猴王的类是由动态代理创建的,它的类名并非孙悟空所属的真实类名,而是类似于$Proxy0这样的代理类名称。而这场战斗,也成为了程序员们传颂的经典案例,提醒着每一个开发者,在追求技术的同时,更要注重本质,警惕那些表面相似却内藏玄机的“假象”。在遥远的东土大唐,有一段传说,讲述着齐天大圣孙悟空与假美猴王之间的纠葛。这不仅仅是一场关于真假美猴王的故事,更是一次程序员智慧的较量,它教会我们,无论是面对程序中的bug还是生活中的难题,都要保持一颗探求真相的心,勇于探索未知,用智慧解决问题。

横竖撇折点 2217

【潜意识Java】从Java反射与泛型深挖程序动态性与类型安全

在 Java 编程领域,反射与泛型是构建灵活、健壮程序的关键特性。这两者不仅深刻影响着代码的组织结构与运行时行为,其背后的原理还与高等数学中的一些概念有着奇妙的联系,尤其是映射(Mapping)的概念。深入探究它们,能让我们站在更高的视角理解程序设计,编写出更具扩展性和安全性的代码。

潜意识Java的博客 800
上一篇: 程序员如何跳出低水平勤奋陷阱
下一篇: 面试前如何准备才能提高成功率(含免费面试资源)
普通网友
博客等级 码龄5年 1265粉丝 108原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值