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

信不信十分钟让你彻底搞懂java反射[通俗易懂]自从搞懂java反射,我是越来越觉得这破公司容不下我了

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

有反射就有正射
在这里插入图片描述

直接new对象就叫正射
在这里插入图片描述

如下

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

三、获取类的所有信息
在这里插入图片描述
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我话说完

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158893.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • PHP入门:在Windows中安装PHP工作环境

    PHP入门:在Windows系统中分别安装PHP工作环境一、什么是LAMP?Linux+Apache+Mysql+Perl/PHP/Python一组常用来搭建动态网站或者服务器的开源软件,本身都是各

    2021年12月20日
    48
  • Vue上传文件操作(没有CV,认真看)

    Vue上传文件操作(没有CV,认真看)项目场景: 通过vue上传文件基本操作问题描述:使用html上传文件时,很容易理解,那么vue文件上传呢?我们学了vue不可能还往里面写原生html的内容吧!先放代码再解释:<template><div><el-form:model=”form”><el-uploadaction=”url”:auto-upload=”false”:on-change=”onchanger”:fil

    2022年10月10日
    2
  • C语言正则表达式

    C语言正则表达式POSIX规定了正则表达式的C语言库函数,详见regex(3)。我们已经学习了很多C语言库函数的用法,读者应该具备自己看懂man手册的能力了。本章介绍了正则表达式在grep、sed、awk中的用法,学习要能够举一反三,请读者根据regex(3)自己总结正则表达式在C语言中的用法,写一些简单的程序,例如验证用户输入的IP地址或email地址格式是否正确。C语言处理正则表达式常用的函数有…

    2022年7月15日
    19
  • Linux命令总结归纳

    Linux命令总结归纳Linux命令总结归纳

    2022年4月22日
    159
  • 用C语言进行Windows编程入门

    用C语言进行Windows编程入门用C语言进行Windows编程入门本文对一般教程或网上有的(如C语言语法等基础)不深入介绍,对初学者易造成疑惑误解或难以找到的内容进行较详尽的介绍。学习C语言很久了,一直面对控制台应用程序(Win32ConsoleApplication),没有漂亮的界面,是不是不爽呀。用C开发图形界面程序,有多种技术方案,本文希望用简单的例子,深入浅出的介绍一种方案——用C和SDK进行图形界面编程。…

    2022年6月18日
    23
  • 原生table样式示例_table好看的css样式

    原生table样式示例_table好看的css样式<div><divclass=”ui-table-head”><tableclass=”ui-table”><colgroup><colstyle=”width:10%”><colstyle=”width:55%”>.

    2025年12月2日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号