信不信十分钟让你彻底搞懂java反射

简介: 概念:反射是Java的一种机制,让我们可以在运行时获取类的信息作用:通过反射,我们可以在程序运行时动态创建对象,还能获取到类的所有信息,比如它的属性、构造器、方法、注解等;

有反射就有正射

d98a7944c07d419186f746a482ec6f34.png

直接new对象就叫正射

bb0849ab62364d36a81efa64c3c7edf1.png

如下

Map<String, String> map = new HashMap<>();
map.put("蔡徐鸡","唱跳rap篮球");

那反射是啥?我先不说反射是啥,概念啥的太虚幻我就不说了,把你绕蒙你这篇文章就白看了,直接举例吧

接着看上面的正射,如果哪天你发现用LinkedHashMap效果更好,然后你噗呲噗呲修改代码

Map<String, String> map = new LinkedHashMap<>();
map.put("蔡徐鸡","唱跳rap篮球");

改完了编译运行没有bug,漂亮,老板可以上线了,噗呲噗呲打包上线;然而过了两天你发现用LinkedHashMap会有隐患,还是得改回去用HashMap,成年人的崩溃如此简单,但是聪明的你想到可以加个判断,根据传入的条件来决定用HashMap还是LinkedHashMap,于是…

public Map<String, String> getMap(String param) {
    Map<String, String> map = null;
    if (param.equals("HashMap")) {
        map = new HashMap<>();
    } else if (param.equals("LinkedHashMap")) {
        map = new LinkedHashMap<>();
     }
   return map;
 }

大功告成,这么难的逻辑都被你实现了,你现在很膨胀,甚至内心隐隐觉得这破公司已经容不下你这尊大佛了


但是某天老大看了你的代码说:小张啊,这里你得用TreeMap;你又要噗呲噗呲改代码,哦豁


------------------------------------------------------正经的分割线------------------------------------------------------


有没有一种办法可以让你不修改代码呢,of course、sure、必须~~滴


这时候反射就派上用场了


概念:反射是Java的一种机制,让我们可以在运行时获取类的信息

作用:通过反射,我们可以在程序运行时动态创建对象,还能获取到类的所有信息,比如它的属性、构造器、方法、注解等;

直接举例吧

public Map<String, String> getMap(String className) {
    Class clazz = Class.forName(className);
    Constructor constructor = clazz.getConstructor();
    return (Map<String, String>) constructor.newInstance();
}

这时候不管你需要什么Map,只要实现了Map接口,你都能通过getMap获得,只需要传入对应Map的全限定名,例如java.util.HashMap / java.util.LinkedHashMap


懂了没,我问你懂了没,没懂的下面留言


------------------------------------------------------不正经的分割线------------------------------------------------------


java中反射的用法非常非常多,常见的有以下这几个:


一、在运行时获取一个类的 Class 对象

二、在运行时构造一个类的实例化对象

三、在运行时获取一个类的所有信息:变量、方法、构造器、注解


一、获取class对象

三种方法

1、类名.class:这种获取方式只有在编译前已经声明了该类的类型才能获取到 Class 对象

Class<HashMap> hashMap= HashMap.class;

2、实例.getClass():通过实例化对象获取该实例的 Class 对象

Map<String, String> hashMap = new HashMap<>();
Class<? extends Map> hashMapClass = hashMap.getClass();

3、Class.forName(“类的全限定名”):通过类的全限定名获取该类的 Class 对象

Class<?> hashMap= Class.forName("java.util.HashMap");

拿到 Class对象就可以对它为所欲为了:调用它的方法、获取属性、获取类信息,总之它在你面前就没有隐私了,好羞羞,嘤~。

二、构造类的实例化对象

通过反射构造一个类的实例方式有2种:

1、Class 对象调用newInstance()方法

Class<?> hashMapClass = Class.forName("java.util.HashMap");
HashMap hashMapInstance = (HashMap) hashMapClass.newInstance();

注意:即使 HashMap已经显式定义了构造方法,通过 newInstance() 创建的实例中,所有属性值都是对应类型的初始值,因为 newInstance() 构造实例会调用默认无参构造器。

2、Constructor 构造器调用newInstance()方法

Class<?> hashMapClass = Class.forName("java.util.HashMap");
Constructor<?> constructor = hashMapClass.getConstructor();
constructor.setAccessible(true);
HashMap newInstance = (HashMap) constructor.newInstance();

通过 getConstructor(Object… paramTypes) 方法指定获取指定参数类型的 Constructor, Constructor 调用 newInstance(Object… paramValues) 时传入构造方法参数的值,同样可以构造一个实例,且内部属性已经被赋值。


通过Class对象调用 newInstance() 会走默认无参构造方法,如果想通过显式构造方法构造实例,需要提前从Class中调用getConstructor()方法获取对应的构造器,通过构造器去实例化对象。


三、获取类的所有信息

20210202143749298.png

1、获取类中的变量(Field)


Field[] getFields():获取类中所有被public修饰的所有变量 Field getField(String

name):根据变量名获取类中的一个变量,该变量必须被public修饰 Field[]

getDeclaredFields():获取类中所有的变量,但无法获取继承下来的变量 Field

getDeclaredField(String name):根据姓名获取类中的某个变量,无法获取继承下来的变量


2、获取类中的方法(Method)


Method[] getMethods():获取类中被public修饰的所有方法

Method getMethod(String name, Class…<?>

paramTypes):根据名字和参数类型获取对应方法,该方法必须被public修饰

Method[] getDeclaredMethods():获取所有方法,但无法获取继承下来的方法

Method getDeclaredMethod(String name, Class…<?>

paramTypes):根据名字和参数类型获取对应方法,无法获取继承下来的方法


3、获取类的构造器(Constructor)


Constuctor[] getConstructors():获取类中所有被public修饰的构造器 Constructor

getConstructor(Class…<?> paramTypes):根据参数类型获取类中某个构造器,该构造器必须被public修饰

Constructor[] getDeclaredConstructors():获取类中所有构造器 Constructor

getDeclaredConstructor(class…<?> paramTypes):根据参数类型获取对应的构造器


反射的应用场景


1、Spring 实例化对象:当程序启动时,Spring 会读取配置文件applicationContext.xml并解析出里面所有的标签实例化到IOC容器中。

2、反射 + 工厂模式:通过反射消除工厂中的多个分支,如果需要生产新的类,无需关注工厂类,工厂类可以应对各种新增的类,反射可以使得程序更加健壮。

3、JDBC连接数据库:使用JDBC连接数据库时,指定连接数据库的驱动类时用到反射加载驱动类


良心建议,家里有条件的同学都把文中代码在自己idea上跑一跑,真正用过以后面试官问到你才有底气


嘤~


ok我话说完


相关文章
|
8天前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
13 2
|
1月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
50 9
Java——反射&枚举
|
1月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
6天前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
6 0
|
1月前
|
Java 程序员 编译器
Java的反射技术reflect
Java的反射技术允许程序在运行时动态加载和操作类,基于字节码文件构建中间语言代码,进而生成机器码在JVM上执行,实现了“一次编译,到处运行”。此技术虽需更多运行时间,但广泛应用于Spring框架的持续集成、动态配置及三大特性(IOC、DI、AOP)中,支持企业级应用的迭代升级和灵活配置管理,适用于集群部署与数据同步场景。
|
1月前
|
存储 安全 Java
扫盲java基础-反射(一)
扫盲java基础-反射(一)
|
1月前
|
Java
扫盲java基础-反射(二)
扫盲java基础-反射(二)
|
3月前
|
安全 Java 测试技术
day26:Java零基础 - 反射
【7月更文挑战第26天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
33 5
|
2月前
|
缓存 安全 Java
【Java 第十篇章】反射
Java 反射技术让程序能在运行时动态获取类信息并操作对象,极大提升了灵活性与扩展性。本文将介绍反射的基本概念、原理及应用,包括如何使用 `Class`、`Field`、`Method` 和 `Constructor` 类进行动态操作。此外,还将探讨反射在动态加载、框架开发与代码测试中的应用场景,并提醒开发者注意性能与安全方面的问题,帮助你更合理地运用这一强大工具。
24 0
|
3月前
|
IDE Java 测试技术
Java进阶之反射
【7月更文挑战第14天】Java反射机制允许在运行时动态获取类信息、创建对象及调用其方法。它基于`Class`类,让我们能访问类的属性、方法、构造器。例如,通过`Class.forName()`加载类,`Class.newInstance()`创建对象,`Method.invoke()`执行方法。反射广泛应用于动态代理、单元测试、序列化及框架中,提供灵活性但牺牲了性能,且可破坏封装性。IDE的代码补全也是反射的应用之一。在使用时需谨慎,避免对私有成员的不当访问。
36 1