【JavaSE】反射机制-基础概述

Catalog

  • JavaSE-反射机制-基础概述
    • 1. 应用场景
    • 2. 优点
    • 3. 缺点
    • 4. Class类解析
    • 5. 获取Class类实例的方式
    • 6. 反射机制是什么
    • 7. 反射机制原理图(老韩)
    • 8. 具体应用

JavaSE-反射机制-基础概述

1. 应用场景

常见的如下:

  1. 当获取到一个未知类型但是知道其中的方法名方法参数的类对象时,可以通过反射机制调用这个方法,甚至于获取到这个类的具体信息。

  2. 通过配置文件动态加载类,动态调用类中的方法和属性。

2. 优点

  1. 动态加载:即使用到某个类时,才对这个类进行加载。

3. 缺点

  1. 使用反射的程序是基于解释执行的,影响程序执行速度。

4. Class类解析

了解反射机制,必须先了解Class类,Class实例是在类加载阶段完成的,即根据字节码文件,通过类加载器来实现Class类实例的加载(将字节码的二进制数据和Class类对象放入内存中)。

关于Class类,该类和普通类的主要区别在于

  • 该类是由系统创建。
  • 每一个普通的类都有一个对应的Class类实例,这个实例包括了普通类的字段、方法、构造函数。

Class类中常用的API

方法描述
getName()获取类的完整名称。
getSimpleName()获取类的简单名称,即去掉包名的类名。
getModifiers()获取类的修饰符,比如publicprivate等。
getFields()获取类的公共字段,包括超类的。
getDeclaredFields()获取类声明的所有字段,包括私有的。
getMethods()获取类的公共方法,包括超类的。
getDeclaredMethods()获取类声明的所有方法,包括私有的。
newInstance()创建类的一个新实例(已过时,不推荐使用)。
getConstructor(Class<?>... parameterTypes)获取指定参数类型的构造函数。
getDeclaredConstructor(Class<?>... parameterTypes)获取类声明的构造函数。

5. 获取Class类实例的方式

  1. 类名.class:通常用于传参。
  2. Class.forname(类的全路径名):在已知类的全路径名的前提下,多用于配置文件,读取类的全路径,加载类。
  3. 实例.getClass():通过对象直接获取Class类的实例。
  4. 对象.getClass().getClassLoader().loadClass(类的全路径名):通过类加载器获取Class类实例。
 /*** 获取Class实例的六种方式*/@Testpublic void testGetClass() throws Exception{//编译期间--->通过调用静态方法forName()获取Class<?> cls = Class.forName(PATH_DOG);System.out.println(cls);//类加载阶段--->通过类名.class获取cls = Dog.class;System.out.println(cls);//运行阶段--->通过对象实例创建Class对象Object dog = cls.newInstance();System.out.println(dog.toString());Class<?> aClass = dog.getClass();System.out.println("运行阶段:" + aClass);//使用类加载器加载Class类的对象Class loadClass = dog.getClass().getClassLoader().loadClass("com.aimin.Dog");//基本数据类型Class<Integer> integerClass = int.class;Class<Character> characterClass = char.class;System.out.println(integerClass);System.out.println(characterClass);Class<Integer> integerClass1 = Integer.TYPE;Class<String> stringClass = String.class;Class<Character> characterClass1 = Character.TYPE;System.out.println(integerClass1);System.out.println(stringClass);System.out.println(characterClass1);}

6. 反射机制是什么

在类加载阶段结束之后,内存中会出现所加载类对应的Class类对象,这个Class类对象包含了所加载类的全部信息,就像一面镜子一样反射了所加载类的全部信息,通过Class类对象就可以操作所加载的全部属性和方法。

7. 反射机制原理图(老韩)

这个图是韩老师课程里面画的图,对类的加载描述地很清晰

Alt

8. 具体应用

  1. 操作类的方法:

    /*** 通过反射获取方法对象,并对方法对象进行操作*/
    public class GetMethodTest {@Testpublic void getMethod() throws Exception{//获取Class类Boss实例Class bossCls = Class.forName("com.aimin.Boss");//获取对象实例Object o = bossCls.newInstance();//获取公有方法对象Method hi = bossCls.getMethod("hi", String.class);//赋值hi.invoke(o, "aimin");//获取私有方法对象Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);//开启暴破say.setAccessible(true);//赋值并执行方法获取返回值//Object result = say.invoke(o, 1, "What's matter with you ?", 'a');//由于"say"方法也是静态方法,所以也可以不指定对象Object result = say.invoke(null, 1, "What's matter with you ?", 'a');System.out.println((String) result);}
    }class Monster {
    }class Boss {//类public int age;private static String name;public Boss() {//构造器}public Monster m1() {return new Monster();}private static String say(int n, String s, char c) {//静态方法return n + " " + s + " " + c;}public void hi(String s) {//普通 public 方法System.out.println("hi " + s);}
    }
    
  2. 操作类的属性:

    /*** 通过反射操作对象(一般类型为Object)的属性*/
    public class OperationFieldTest {@Testpublic void operationField() throws Exception{//获取Class类对象Class stuCls = Class.forName("com.aimin.Student");//获取类实例Object stu = stuCls.newInstance();//通过属性名获取属性对象---公共字段Field age = stuCls.getField("age");//赋值age.set(stu, 22);System.out.println(age.get(stu));//通过属性名获取属性对象---私有静态字段//由于静态字段与类加载有关,即静态对象是所有类实例共用的,所以在赋值的时候可以不指定对象实例Field name = stuCls.getDeclaredField("name");//开启暴破name.setAccessible(true);//赋值//name.set(null, "aimin");name.set(stu, "WangBB");System.out.println(name.get(null));}}class Student {//类public int age;private static String name;public Student() {//构造器}public String toString() {return "Student [age=" + age + ", name=" + name + "]";}
    }
    
  3. 获取类实例

    /*** 通过反射获取类实例*/
    public class NewInstanceTest {@Testpublic void getInstanceByClass() throws Exception{//获取User类Class类对象Class userCls = Class.forName("com.aimin.User");//通过公有无参构造器创建对象Object user01 = userCls.newInstance();System.out.println("公有无参构造器" + user01);//通过公有有参构造器创建对象Constructor constructor = userCls.getConstructor(String.class);Object aimin = constructor.newInstance("aimin");System.out.println("公有有参构造器" + aimin);//通过私有构造器创建对象//1. 获取到私有构造器Constructor declaredConstructor = userCls.getDeclaredConstructor(int.class, String.class);//2. 开启暴破,类四暴力破解,之后才能获取到私有构造器declaredConstructor.setAccessible(true);Object test = declaredConstructor.newInstance(1, "test");System.out.println(test);}
    }class User { //User 类private int age = 10;private String name = "韩顺平教育";public User() {//无参 public}public User(String name) {//public 的有参构造器this.name = name;}private User(int age, String name) {//private 有参构造器this.age = age;this.name = name;}public String toString() {return "User [age=" + age + ", name=" + name + "]";}
    }

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

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

相关文章

香港优才计划避坑指南及过来人建议,这6种行为会毁了你的香港身份!

香港优才计划是一项香港人才引进政策&#xff0c;如果你想真正落户香港&#xff0c;那么就需要了解清楚香港优才从申请到永居的整个流程&#xff0c;并且要注意维护好香港身份。 如果操作不当&#xff0c;可能会中断你来之不易的香港身份。 本文总结了香港优才整个流程中&…

做抖店的门槛高吗?一个月的时间能入门吗?基础问题解答如下

我是王路飞。 抖店&#xff0c;依旧是普通人做抖音最好的渠道&#xff0c;没有之一&#xff0c;依旧值得我们all in。 这是我对2024年抖音小店的看法和态度&#xff0c; 那么做抖店的门槛高吗&#xff1f;新手用一个月的时间能做到入门吗&#xff1f;投入和回报的数据是多少…

DELL服务器配置ILO(idrac)地址、修改管理员密码

服务器型号&#xff1a;DELL PowerEdge R630 1、重启服务器选择F2进入BIOS 2、重启服务器选择F2进入BIOS 3、选择“Network” 4、配置iDRAC的IP&#xff0c;掩码网关&#xff0c;DNS等信息 5、Esc返回&#xff0c;下滑选择“User Configuration” 6、配置iDRAC的用户名密码以及…

1-1 CubeMX配置第一个RTOS工程

CubeMX配置第一个RTOS工程 1&#xff1a; 打开cubeMX软件选择单片机型号 软件刚刚安装仍然需要加载 配置RCC时钟&#xff1a;开启RCC时钟 打开芯片使能仿真功能 这里使用为GD32芯片&#xff0c;芯片的引脚由原理图给出 PA8 与PE13是引脚&#xff1a;将引脚配置为输出模式 配置G…

Blender雕刻建模_笔刷

1.雕刻模式 雕刻Scuplt&#xff0c;一种常用的建模方式 -选中物体&#xff0c;进入雕刻模式 -重构网格&#xff08;修改体素大小&#xff0c;点击重构网格&#xff09;给物体添加更多面 -选择笔刷&#xff0c;雕刻 -退出雕刻模式 2.重构网格 一种按体积的细分方式&#xf…

Win7远程桌面连接不上:原因及专业解决方案

Win7远程桌面连接作为一种方便的工具&#xff0c;使得用户可以从一台计算机远程访问和操作另一台计算机。然而&#xff0c;有时用户可能会遇到Win7远程桌面连接不上的情况&#xff0c;这可能是由于多种原因导致的。 一、原因分析 1. 网络设置问题&#xff1a;确保计算机与远程…

【十大排序算法】----选择排序(详细图解分析+实现,小白一看就会)

目录 一&#xff1a;选择排序——原理 二&#xff1a;选择排序——分析 三&#xff1a;选择排序——实现 四&#xff1a;选择排序——优化 五&#xff1a;选择排序——效率 一&#xff1a;选择排序——原理 选择排序的原理&#xff1a;通过遍历数组&#xff0c;选出该数组…

数据结构~~带环链表的环开始的节点位置**两种方法

1.带环链表环开始的位置 &#xff08;1&#xff09;上面的这个测试用例使用的是包含了4个节点的带环链表&#xff0c;我们要找的就是链表里面的环开始的节点的位置&#xff0c;拿这个测试用例而言&#xff0c;就是2这个节点&#xff0c;从这个节点开始&#xff0c;我们的链表就…

【数据结构】栈的实现(顺序栈)

文章目录 栈的概念和结构栈的实现1.顺序存储结构栈的定义初始化栈入栈出栈获取栈顶元素获取栈中有效元素个数检测栈是否为空&#xff0c;如果为空返回非零结果&#xff0c;如果不为空返回0销毁栈栈的打印 完整代码&#xff08;包括测试代码&#xff09;Stack.hStack.ctest.c 栈…

代码随想录Day 47|Leetcode|Python|392.判断子序列 ● 115.不同的子序列

392.判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新字符串。&#xff08;例如&#xff0c;"ace"是"abcde"的…

可以当回音壁使用的蓝牙条形音箱中应用的蓝牙芯片

条形音箱&#xff08;英语&#xff1a;Soundbar&#xff09;是一个有立体声效的音箱&#xff0c;通常放置于屏幕的上方或下方&#xff0c;基于声学的考虑&#xff0c;此种音箱多为长条形设计&#xff0c;故名。无线蓝牙条形音箱也一样&#xff0c;银色磨砂铝合金中框。搭配黑色…

JavaScript基础知识强化:变量提升、作用域逻辑及TDZ的全面解析

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 ⭐️ 引言&#x1f3af; 变量提升(Hoisting)&#x1f47b; 暂时性死区&#xff08;Temporal Dead Zone, TDZ&#xff09;解释&#x1f4e6; var声明&#x1f512; let与const声明&#x1f4d6; 函数声明 与 函数表达式函数声…