Java反射机制入门:解锁运行时类信息的秘密

反射技术:

  • 其实就是对类进行解剖的技术
  • 类中有什么?
  • 构造方法
    • 成员方法
    • 成员变量

结论:反射技术就是把一个类进行了解剖,然后获取到 构造方法、成员变量、成员方法


反射技术的应用案例:

  • idea
  • 框架技术:Spring

想要使用反射技术有一个必备条件

  • Class对象
  • 原因:.class文件由类加载器读取并创建Class对象。Class对象中存储了.class文件中的内容:构造方法、成员变量、成员方法

反射技术的作用

使用反射技术,可以对类进行解剖,可以获取到类中的:构造方法、成员变量、成员方法

  • 构造方法: 可以创建对象
  • 成员方法: 可以调用执行
  • 成员变量: 赋值、取值

反射技术的作用:

  • 不用使用new关键字,就可以创建对象
  • 不用使用"对象名.方法"形式,就可以调用方法
  • 不用使用"对象名.属性"形式,就可以给属性赋值、取值
  • 通常在类中属性,都被修饰为private(私有的:外部不能访问)
  • 反射技术,可以做到对私有成员进行操作

 

"cn.itcast.pojo.Student" stu = new cn.itcast.pojo.Student();给一个字符串:"cn.icast.pojo.Student"创建一个对象:?????   //使用new做不到  使用反射技术可以实现

给一个Student.class程序在运行中,不能停止, 动态的获取一个Student.class//使用反射技术,可v

小结

反射技术 :对类进行解剖的技术

反射技术的作用:可以不通过传统方式,来实现类的实例化、方法的调用

  • 实现的提前:需要使用Class对象

反射:Class类

路径

  1. Class类
  2. 获取Class类对象的方式
  3. Class类中的常用方法

Class类

  • Class就是用来描述正在运行的java类型
  • Class类的实例表示Java中任何正在运行的类型,每一个类型都有与之对应的Class对象
    • 比如:类,接口,枚举,注解,数组,基本数据类型,void 都有与之对应的Class对象
类名.class
接口名.class
int.class
boolean.class
array.class   

获取Class对象

获取Class类对象的方式有3种:

方式一:类型名.class   //Student.class
方式二:对象.getClass()  //对象名.getClass()
方式三:Class.forName(String className) //className是全路径类名 = 包名+类型名
//方式1:类型名.class
//应用场景: 当类名明确时,可以直接使用"类名.class"
Class clz = String.class 
Class clz = int.class 
Class clz = double.class//方式2:对象.getClass()
//应用场景:通常是应用方法中public void method(Student stu){Class clz = stu.getClass();   } //方式3: Class.forName("类的全名称");//带有包名的类
//应用场景: 通常使用在读取配置文件中的类型
pro.properties文件
--------------文件内容------------------    
className=cn.icast.pojo.Student   
---------------------------------------   
//代码实现    
ResourceBundler r = ResourceBundler.getBundler("pro");
String className = r.getString("className");//"cn.icast.pojo.Student"Class StudentClass = Class.forName(className);//className="cn.icast.pojo.Student" //当获取到Class对象了,就可以对类进行解剖了

Class类中的常用方法

String getSimpleName()  // 获得类名字符串:类名
String getName()   // 获得类全名:包名+类名
T newInstance() // 创建Class对象关联类的对象 (前提:类中有一个无参构造方法)//示例:Studentod类    cn.itcast.pojo.Student     //public Student(){}Class stuClass = Student.class;Object obj = stuClass.newInstance();//调用Student()  创建Student对象Student stu = (Student) obj;

代码实现

public class Test01 {@Testpublic void testMethod3() throws ClassNotFoundException, IllegalAccessException, InstantiationException {Class stuClass = Class.forName("com.itheima.cls.demo2.Student");Student stu = (Student) stuClass.newInstance();stu.study();}@Testpublic void testMethod2() throws IllegalAccessException, InstantiationException {Student stu =new Student();//对象名.getClass()Class studentClass = stu.getClass();Student student = (Student) studentClass.newInstance();student.study();}@Testpublic void testMethod1() throws IllegalAccessException, InstantiationException {// 类型名.classClass studentClass = Student.class;//System.out.println(studentClass);System.out.println("带有包名的类:"+studentClass.getName());System.out.println("类名:"+studentClass.getSimpleName());//实例化Student对象Object obj = studentClass.newInstance();Student stu = (Student) obj;stu.age=20;stu.name="张三";System.out.println(stu.name+"==="+stu.age);stu.study();}
}

获取Class对象的方式:

  1. 类型名.class //明确了具体的类型时,直接使用:类名.class
  2. 对象名.getClass() //当方法中传递的对象时,使用:对象名.getClass()
  3. Class类中的静态方法:forName("带有包名的类") //从配置文件中读取到类的全名称时

反射:构造器

路径

  1. Constructor类
  2. 获取构造器Constructor对象的方式
  3. Constructor类中常用方法

构造方法对应的类型:  Constructor类型
字段:Field
方法:Method

Constructor类

  • 代表构造方法(构造器)
  • 类中的每一个构造方法都是一个Constructor类的对象

反射技术中构造器的目的:

  • 获得Constructor对象来创建类的对象
大白话:不使用new关键字,通过Constructor来创建对象

获取Constructor对象的方式

Constructor对象的获取和Class类中方法有关:

Constructor[] getConstructors()//获得类中的所有构造方法对象,只能获得public的Constructor[] getDeclaredConstructors()//获得类中的所有构造方法对象//可以是public、protected、(默认)、private修饰符的构造方法    Constructor getConstructor( Class... parameterTypes)//根据参数类型获得对应的Constructor对象   获取public修饰的//只能获得public修饰的构造方法
/*示例: Student       public Student(String name, int age)    public Student(int age) Class stuClass = Student.class;//根据给定的参数类型,来获取匹配的构造器对象Constructor c = stuClass.getConstructor( String.class , int.class );
*/  Constructor getDeclaredConstructor(Class... parameterTypes)//根据参数类型获得对应的Constructor对象//可以是public、protected、默认、private修饰符的构造方法

Constructor类常用方法

T newInstance(Object... initargs)//根据指定的参数创建对象
/*Class stuClass = Student.class;//根据给定的参数类型,来获取匹配的构造器对象Constructor c = stuClass.getConstructor( String.class , int.class );//使用构造器对象,来实例化Studentc.newInstance( "张三", 22 );//Student(String name, int age)//无参构造Constructor c = stuClass.getConstructor();Student stu = (Student) c.newInstance();
*/    void setAccessible(true)//应用场景:仅适用于访问有权限检查的成员//设置"暴力反射" ——是否取消权限检查,true取消权限检查,false表示不取消

代码实现:

public class Test1 {@Testpublic void testMethod1() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取构造器的步骤/*1、先获取到Class对象2、使用Class对象中的方法,获取Constructor对象3、使用Constructor对象,实例化类*///获取Class对象(Student.class)Class stuClass = Student.class;//获取Constructor对象: public Student()Constructor con1 = stuClass.getConstructor();System.out.println(con1);Student stu = (Student)con1.();stu.name="小崔";System.out.println(stu.name);}
}

Constructor类:

  • 代表类中的一个构造方法

获取Constructor类的方式:

//获取public修饰的构造方法
Constructor getConstructor(Class... parameterTypes)//获取非public修饰的方法
Constructor getDeclaredConstructor(Class... parameterTypes)
Object newInstance(Object... param)  //利用构造器对象,实例化自定义对象void setAccessible(true) //消除JVM对权限的检查操作 (一次性的。只是对当前操作去除)    

反射:使用构造器创建对象

路径

  1. 案例:使用无参构造器创建对象
  2. 案例:使用有参构造器创建对象
  3. 案例:使用私有构造器创建对象
  4. 案例:使用私有构造器创建对象

案例:使用无参构造器创建对象

@Testpublic void testMethod1() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取Class对象(Student.class)Class stuClass = Student.class;//利用Class对象,来获取构造器对象Constructor con = stuClass.getConstructor();//方法中的参数为可变参数,可以不传递值//使用Constructor对象中的方法,来实例化Student类对象Student stu = (Student) con.newInstance();//方法中的参数是可变参数stu.study();}

案例:使用有参构造器创建对象

//有参构造方法@Testpublic void testMethod2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取Class对象(Student.class)Class stuClass = Student.class;//public Student(String name, int age, String gender)//获取带有参数的构造器对象//参数:是用来设置构造方法中参数的类型是什么Constructor con = stuClass.getConstructor(String.class, int.class, String.class);//实例化有参构造方法//参数:要传递给Student(String name, int age, String gender)的数据Student stu = (Student) con.newInstance("熊大", 22, "男");//调用对象中的方法stu.study();}

案例:使用私有构造器创建对象

@Testpublic void testMethod3() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取Class对象(Student.class)Class stuClass = Student.class;// private Student(String name)//获取私有构造器对象Constructor con = stuClass.getDeclaredConstructor(String.class);//当需要对私有成员操作时,需要先取消JVM对访问权限的检查操作con.setAccessible(true);//暴力破解(取消权限检查) //仅在当前次取消//使用私有构造器,实例化Student对象Student stu = (Student) con.newInstance("文平");System.out.println(stu.name);stu.study();}

反射:方法

路径

  1. Method类
  2. 获取Method对象的方式
  3. Method类常用方法

Method

Method类

  • 代表一个成员方法
    • 每一个成员方法都是一个Method类的对象

反射技术中使用Method的目的:

  • 通过Method对象来调用成员方法

获取Method对象的方式

Method对象的获取和Class类中方法有关:

Method[] getMethods();//获得当前类和其父类中的所有public成员方法对象,返回数组Method[] getDeclaredMethods();//获得当前类中的所有成员方法对象,返回数组//只获得本类的,包括public、protected、默认、private的Method getMethod(String name,Class...args);//根据方法名和参数类型获得对应的成员方法对象,只能获得public的//参数说明:name : 类中方法的名字args : 方法中参数类型的Class     例:int.class     Method getDeclaredMethod(String name,Class...args);//根据方法名和参数类型获得对应的成员方法对象,包括public、protected、(默认)、private的

Method类常用方法

//使用方法对象,调用对象中的方法执行(入栈执行)
Object invoke(Object obj, Object... args) // obj: 对象   //"对象名.方法"// args:调用方法时传递的实参
//返回值: Object类型      void setAccessible(true)// 设置"暴力访问"  ——是否取消权限检查,true取消权限检查,false表示不取消

代码实现:

//获取Method对象的步骤:
1、先获取Class对象
2、使用Class对象,获取Method对象
3、使用Method对象,执行方法public class Test01 {@Testpublic void testMethod1() throws ClassNotFoundException {//获取Class对象Class stuClass  = Class.forName("com.itheima.method.demo1.Student");//使用Class对象,获取Method对象Method[] methods = stuClass.getMethods();//获取本类及父类中所有的public方法for (Method m : methods){System.out.println(m);}}@Testpublic void testMethod2() throws ClassNotFoundException {//获取Class对象Class stuClass  = Class.forName("com.itheima.method.demo1.Student");//使用Class对象,获取Method对象Method[] methods = stuClass.getDeclaredMethods();//获取本类中所有方法(包含私有)for (Method m : methods){System.out.println(m);}}
}    

反射:方法调用

路径

  1. 案例:调用无参无返回值的方法
  2. 案例:调用有参有返回值的方法
  3. 案例:调用私有方法
  4. 案例:调用静态方法

案例:调用无参无返回值的方法

 @Testpublic void testMethod1() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取Class对象Class stuClass = Student.class;//因为在调用Method时,需要传递Student对象Constructor con = stuClass.getConstructor();Student stu = (Student)con.newInstance();//获取public void study()方法的对象Method method = stuClass.getMethod("study");//使用Method对象 执行study()方法method.invoke( stu );}

案例:调用有参有返回值的方法

/有参有返回值@Testpublic void testMethod2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取Class对象Class stuClass = Student.class;//因为在调用Method时,需要传递Student对象Constructor con = stuClass.getConstructor();Student stu = (Student)con.newInstance();//获取public String sayHello(String name)方法的Method对象Method method = stuClass.getMethod("sayHello", String.class);//调用method方法Object result = method.invoke(stu,"波波");System.out.println(result);}

案例:调用私有方法

//私有方法@Testpublic void testMethod3() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {//获取Class对象Class stuClass = Student.class;//因为在调用Method时,需要传递Student对象Constructor con = stuClass.getConstructor();Student stu = (Student)con.newInstance();//获取 private void eat(String name)方法的Method对象Method method = stuClass.getDeclaredMethod("eat", String.class);//去除JVM对当前次权限的检查method.setAccessible(true);//执行method方法method.invoke(stu,"红烧肉");}

案例:调用静态方法

//静态方法@Testpublic void testMethod4() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {//获取Class对象Class stuClass = Student.class;//静态方法的调用不需要对象。"类名.静态方法()"//获取public static void sleep()方法的Method对象Method method = stuClass.getMethod("sleep");//执行静态方法method.invoke(null);//不需要传递对象(null就表示执行静态方法)}

Method对象的使用步骤:

1、获取Class对象

2、基于Class对象,获取Method对象

//有参方法
Method method = Class对象.getMethod("方法名",参数1类型.class,参数2类型.class ...);
//无参方法
Method method = class对象.getMethod("方法名");

3、使用Method对象,执行方法

//调用非静态方法
method对象.invoke(实例对象,方法中需要的实参)//调用静态方法
method对象.invoke(null,方法中需要的实参)    

反射的作用案例演示

  • 作用反射是框架的灵魂!框架的底层一定会用到反射技术。
  • 需求:要把猫的睡觉方法 变成 狗的吃饭方法
  • 效果:使用反射+Properties完成配置文件。把需要修改的灵活的内容写在配置文件中,代码不需要做任何的改动。
    • 案例演示
public class Dog {public void eat(){System.out.println("狗爱吃肉");}public void sleep(){System.out.println("狗睡觉流口水");}}public class Cat {public void eat(){System.out.println("猫爱吃鱼");}public void sleep(){System.out.println("猫睡觉打呼噜");}
}public class Demo {public static void main(String[] args) throws Exception{//不使用反射//需求:   要把猫的睡觉方法  变成  狗的吃饭方法//Dog d = new Dog();//d.eat();//使用反射//propertiesProperties pro = new Properties();//load():可以把文件中的键值对读取到集合中FileReader fr = new FileReader("day21\\aaa.txt");pro.load(fr);//通过键获取值String cn = pro.getProperty("className");String mn = pro.getProperty("methodName");//获取字节码对象Class c = Class.forName(cn);//获取空参构造Constructor con = c.getConstructor();//执行构造方法Object o = con.newInstance();//获取方法Method m = c.getMethod(mn);//执行方法m.invoke(o);}}配置文件:className=com.itheima_05.CatmethodName=sleep

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/430941.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过document获取节点元素

1.层级节点 <ul><li id"li1">1</li><li>2</li><li id"li3">3</li><li>4</li><li>5</li></ul><script>//获取id名为li1的元素赋值给li1let li1document.getElementById(li…

爬虫----webpack

目录 一. 什么是webpack 出现的原因&#xff1a;同名函数 概念: 特征&#xff1a;大量缩进 webpack的格式 简单的webpack格式&#xff1a; 详细的webpack格式&#xff1a; 几个参数的运用 1. webpack数组形式 2. webpack对象格式 3.多个js文件打包 打印要扣的代码 …

【chromedriver编译-绕过selenium机器人检测】

有小伙伴说使用selenium没能绕过机器人检测&#xff0c;盘他。 selenium机器人检测有2种&#xff0c;一是cdp检测&#xff0c;二是webdriver特征检测。cdp检测前面的博客已写过&#xff0c;这里就提下webdriver特征检测。一、selenium简介 Selenium 是一个强大的工具&#xff…

单片机带隙电压基准电路

单片机带隙电压基准电路 一、带隙电压基准电路概述 带隙电压基准电路在单片机中占据着至关重要的地位。它能够为各种模拟集成电路提供稳定的参考电压&#xff0c;确保电路的正常运行。例如&#xff0c;在高精度的比较器中&#xff0c;带隙电压基准电路可以提供一个精确的参考…

linux 的 sed 命令的 使用学习

&#xff08;1&#xff09; sed 概述&#xff1a; &#xff08;2&#xff09; 首先谢谢 b 站这位老师&#xff0c;这位专家的完美讲解 讲解继续&#xff1a; &#xff08;3&#xff09; 关于 sed 里的模式&#xff1a; &#xff08;4&#xff09; sed 支持的常用的对文本编辑的…

Matlab|考虑柔性负荷的综合能源系统低碳经济优化调度

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 程序主要实现的是考虑柔性负荷的综合能源系统低碳经济优化调度&#xff0c;模型参考《考虑柔性负荷的综合能源系统低碳经济优化调度》&#xff0c;求解方法采用的是混合整数规划算法&#xff0c;通过matlabc…

【设计模式】UML类图

目录 前言 一、类图概述 二、类图的作用 三、类图表示法 四、类之间关系的表示方法 1. 关联关系 1.1 单向关联 1.2 双向关联 1.3 自关联 2. 聚合关系 3. 组合关系 4. 依赖关系 5. 继承关系 6. 实现关系 总结 前言 统一建模语言&#xff08; Unified Modeling La…

如何快速上手一个Github的开源项目

程序研发领域正是有一些热衷开源的小伙伴&#xff0c;技能迭代才能如此的迅速&#xff0c;因此&#xff0c;快速上手一个GitHub上的开源项目&#xff0c;基本上已经变成很个程序员小伙伴必须掌握的技能&#xff0c;因为终究你会应用到其中的一个或多个项目&#xff0c;帮助自己…

【资源一号04A卫星(中巴地球资源卫星04A星)】

资源一号04A卫星&#xff08;中巴地球资源卫星04A星&#xff09; 资源一号04A卫星&#xff0c;全称为中巴地球资源卫星04A星&#xff08;CBERS-04A&#xff09;&#xff0c;是中国与巴西两国合作研制的第六颗地球资源卫星。以下是对该卫星的详细介绍&#xff1a; 一、基本信…

打造灵活DateTimePicker日期时间选择器组件:轻松实现时间的独立清除功能

element ui中日期和时间选择器&#xff08;DateTimePicker&#xff09;是一个常见且重要的组件。它允许用户轻松地选择日期和时间&#xff0c;极大地提升了用户体验。然而&#xff0c;在某些场景下&#xff0c;用户可能需要更细粒度的控制&#xff0c;例如单独清除已选择的时间…

【资源一号02C卫星】

资源一号02C卫星 资源一号02C卫星是中国航天科技集团公司所属中国空间技术研究院负责研制生产的一颗重要遥感卫星。以下是关于该卫星的详细介绍&#xff1a; 一、基本信息 发射时间&#xff1a;2011年12月22日11时26分发射地点&#xff1a;中国太原卫星发射中心运载火箭&am…

基于区块链的相亲交易系统源码解析

随着区块链技术的成熟与发展&#xff0c;其去中心化、不可篡改的特性逐渐被应用于各行各业。特别是在婚恋市场中&#xff0c;区块链技术的应用为相亲平台带来了新的可能性 。本文将探讨如何利用区块链技术构建一个透明、高效的相亲交易系统&#xff0c;并提供部分源码示例。 区…

提前解锁 Vue 3.5 的新特性

Vue 3.5 是 Vue.js 新发布的版本&#xff0c;虽然没有引入重大变更&#xff0c;但带来了许多实用的增强功能、内部优化和性能改进。 1. 响应式系统优化 Vue 3.5 进一步优化了响应式系统的性能&#xff0c;并且减少内存占用。尤其在处理大型或深度嵌套的响应式数组时&#xff…

Contact Form 7最新5.9.8版错误修复方案

最近有多位用户反应Contact Form 7最新5.9.8版的管理页面有错误如下图所示 具体错误文件的路径为wp-content\plugins\contact-form-7\admin\includes\welcome-panel.php on line 153 找到welcome-panel.php这个文件编辑它&#xff0c;将如下图选中的部分删除 删除以后&#xf…

显示和隐藏图片【JavaScript】

使用 JavaScript 来实现显示和隐藏图片。下面是一个简单的示例&#xff0c;展示如何通过按钮点击来切换图片的可见性。 实现效果: 代码&#xff1a; <!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name&…

python爬虫案例——抓取链家租房信息

文章目录 1、任务目标2、分析网页3、编写代码1、任务目标 目标站点:链家租房版块(https://bj.lianjia.com/zufang/) 要求:抓取该链接下前5页所有的租房信息,包括:标题、详情信息、详情链接、价格 如: 2、分析网页 用浏览器打开链接,按F12或右键检查,进入开发者模式;因…

计算机毕业设计 美发管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

OpenAI converting API code from GPT-3 to chatGPT-3.5

题意&#xff1a;将OpenAI API代码从GPT-3转换为ChatGPT-3.5 问题背景&#xff1a; Below is my working code for the GPT-3 API. I am having trouble converting it to work with chatGPT-3.5. 以下是我用于GPT-3 API的工作代码。我在将其转换为适用于ChatGPT-3.5时遇到了…

前端开发之装饰器模式

介绍 装饰器模式 是在不修改对象内部结构的情况下&#xff0c;动态地给对象添加功能的一种设计模式。在软件开发中&#xff0c;有时候我们需要为已有对象添加一些额外的行为&#xff0c;但不希望修改该对象的代码&#xff0c;装饰器模式可以很好的满足这一需求。 在TypeScrip…

echarts map地图动态下钻,自定义标注,自定义tooltip弹窗【完整demo版本】

在数据可视化中&#xff0c;地图是很重要的一个环节&#xff0c;很多时候需要展现的不仅是国家地图&#xff0c;还需要能从国家进入到省市。这个逐级进入的过程就是我们今天说的地图下钻。 地图下钻看起来很屌、很高大上&#xff0c;但是仔细琢磨一下&#xff0c;技术实现上真的…