信不信十分钟让你彻底搞懂java反射[通俗易懂]

信不信十分钟让你彻底搞懂java反射[通俗易懂]有反射就有正射 直接 new 对象就叫正射 如下 Map map new HashMap map put 蔡徐鸡 唱跳 rap 篮球 那反射是啥 我先不说反射是啥 概念啥的太虚幻我就不说了 把你绕蒙你这篇文章就白看了 直接举例吧 接着看上面的正射 如果哪天你发现用 LinkedHashMa 效果更好 然后你噗呲噗呲修改代码 Map map new LinkedHashMa

有反射就有正射

直接new对象就叫正射

如下

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

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

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

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

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

public Map getMap(String param) { 

Map 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 getMap(String className) { 

Class clazz = Class.forName(className);
Constructor constructor = clazz.getConstructor();
return (Map) constructor.newInstance();
}

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

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

——————————————————不正经的分割线——————————————————

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

一、在运行时获取一个类的 Class 对象
二、在运行时构造一个类的实例化对象
三、在运行时获取一个类的所有信息:变量、方法、构造器、注解

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

Class hashMap= HashMap.class;

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

Map hashMap = new HashMap<>();
Class 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()方法获取对应的构造器,通过构造器去实例化对象。

三、获取类的所有信息


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上跑一跑,真正用过以后面试官问到你才有底气

编程小号
上一篇 2025-01-16 16:51
下一篇 2025-01-16 16:40

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/148912.html