Java基础-反射

文章目录

    • 1.快速入门
        • 1.案例引入
        • 2.代码实例
        • 3.反射机制原理图
    • 2.反射相关类
        • 1.反射获取类的成员
          • 代码实例
          • 结果
        • 2.反射调用优化
          • 1.关闭访问检查
          • 2.代码实例
    • 3.Class类
        • 1.类图
        • 2.基本介绍
        • 3.Class类常用方法
          • 代码实例
          • 结果
        • 4.获取Class类对象
          • 代码实例
          • 结果
        • 5.哪些类型有Class对象
    • 4.类加载
        • 1.基本介绍
        • 2.静态加载与动态加载实例
        • 3.类加载流程图
        • 4.简要理解类加载
    • 5.反射获取类的结构信息
        • 第一组
          • 代码实例
          • 结果
        • 第二组
          • 代码实例
          • 结果
        • 第三组
          • 代码实例
          • 结果
        • 第四组
          • 代码实例
          • 结果
    • 6.反射爆破
        • 1.反射爆破创建实例
          • 代码实例
          • 结果
        • 2.反射爆破操作属性
          • 代码实例
          • 结果
        • 3.反射爆破操作方法
          • 代码实例
          • 结果
    • 7.本章练习
        • 练习一
          • 题目
          • 代码
          • 结果
        • 练习二
          • 题目
          • 代码
          • 结果

1.快速入门

1.案例引入

image-20240114103703457

2.代码实例
package Reflection_;import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;/*** @author 孙显圣* @version 1.0*/
public class ReflectionQuestion {public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {//使用反射来根据配置文件来调用方法//1.读取配置文件,获取类的全路径和方法Properties properties = new Properties();properties.load(new FileInputStream("src\\cat.properties"));String fullclasspath = properties.getProperty("fullclasspath");String method = properties.getProperty("method");//2.加载类,返回Class类型的对象clsClass<?> cls = Class.forName(fullclasspath);//3.获取加载类的对象实例Object o = cls.newInstance();//4.获取加载类的方法对象Method method1 = cls.getMethod(method);//5.调用这个方法method1.invoke(o);}
}

image-20240114103811437

3.反射机制原理图

image-20240114105523348

2.反射相关类

image-20240114142658917

1.反射获取类的成员
代码实例
package Reflection_;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;/*** @author 孙显圣* @version 1.0*/
public class Refection01 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {//类加载,获取Class类型Class<?> cls = Class.forName("Reflection_.Cat");//反射获取属性Field name = cls.getField("name"); //不能获取私有的System.out.println(name);//反射获取构造器Constructor<?> constructor = cls.getConstructor(String.class);System.out.println(constructor);//反射获取方法Method hi = cls.getMethod("hi");System.out.println(hi);}
}
结果

image-20240114142738106

2.反射调用优化
1.关闭访问检查
  1. Method,Field,Constructor对象都有setAccessible方法
  2. setAccessible作用是启动和禁用访问安全检查的开关,true为取消
2.代码实例
package Reflection_;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/*** @author 孙显圣* @version 1.0*/
public class Refection02 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {//传统方法来调用hinew Cat().hi();//使用反射来调用hiClass<?> cls = Class.forName("Reflection_.Cat");//获取方法对象Method hi = cls.getMethod("hi");//获取加载类的对象实例Object o = cls.newInstance();//关闭访问检查,提高速度hi.setAccessible(true);//执行方法hi.invoke(o);}
}

3.Class类

1.类图

image-20240114144708984

2.基本介绍

image-20240114150034519

  1. Class也是类,因此也继承Object类
  2. Class类对象不是new出来的,而是系统创建的
  3. 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
  4. 每个类的实例都会记得自己是由哪个Class实例所生成的
  5. 通过Class对象,可以完整地得到一个类的完整结构,通过一系列API
  6. Class类对象是放在堆的,可以理解为是把方法区中的元数据保存到Class类对象中,方便获取其中的成员
  7. 类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据
3.Class类常用方法
代码实例
package Reflection_;import java.lang.reflect.Field;/*** @author 孙显圣* @version 1.0*/
public class Class01 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {//定义全路径String allClassPath = "Reflection_.Cat";//获取Cat类的Class类对象Class<?> cls = Class.forName(allClassPath);//显示该对象是哪个类的Class对象System.out.println(cls);//显示运行类型System.out.println(cls.getClass());//获取包名System.out.println(cls.getPackage().getName());//获取全类名System.out.println(cls.getName());//通过反射创建对象Cat o = (Cat) cls.newInstance();o.hi(); //调用Cat类的方法//通过反射获取属性Field name = cls.getField("name");//通过反射给属性赋值name.set(o,"小猫");System.out.println(name.get(o));//遍历所有属性Field[] fields = cls.getFields();for (Field field : fields) {System.out.println(field.get(o));}}
}
结果

image-20240114152919844

4.获取Class类对象
代码实例
package Reflection_;/*** @author 孙显圣* @version 1.0*/
public class Class02 {public static void main(String[] args) throws Exception {//获取反射对象的六种方式//1. Class.forNameString classAllPath = "Reflection_.Cat"; //一般通过读取配置文件获取,在框架中用的较多Class<?> aClass = Class.forName(classAllPath);//2. 类名.class,应用场景:用于参数传递System.out.println(Cat.class);//3. 对象.getClass(),应用场景:有对象实例,获取运行类型System.out.println(new Cat().getClass());//4. 通过类加载器获取ClassLoader classLoader = Cat.class.getClassLoader(); //获取类加载器Class<?> aClass1 = classLoader.loadClass(classAllPath);//5.基本数据类型 类型.classClass<Integer> integerClass = int.class;Class<Character> characterClass = char.class;System.out.println(integerClass);System.out.println(characterClass);//6.基本数据类型对应的包装类 类型.TYPEClass<Integer> type = Integer.TYPE;Class<Character> type1 = Character.TYPE;System.out.println(type);System.out.println(type1);}
}
结果

image-20240114155716147

5.哪些类型有Class对象

image-20240114160053097

4.类加载

1.基本介绍
  1. 静态加载:编译时加载相关的类,如果没有则报错
  2. 动态加载:运行时才加载需要的类,如果运行时不使用该类,即使不存在该类,则不报错,降低了依赖性
  3. 类加载时机:
    1. 当创建对象时
    2. 当子类被加载时,父类也会被加载
    3. 调用类中的静态成员时
    4. 通过反射(动态加载)
2.静态加载与动态加载实例

在这里如果没有Dog类则直接编译报错,但是如果没有Person类,只要不执行case2则不会报错

3.类加载流程图

image-20240114164018137

image-20240114164159830

image-20240114164548582

image-20240114165345356

image-20240114165352321

image-20240114165618491

image-20240114170514602

4.简要理解类加载
  1. 加载:得到Class类对象
  2. 连接:静态默认初始化,常量直接初始化
  3. 合并初始化:将静态代码合并,根据语句内容进行初始化

5.反射获取类的结构信息

第一组

image-20240114185352788

代码实例
package Reflection_;import org.junit.jupiter.api.Test;import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;/*** @author 孙显圣* @version 1.0*/
public class ReflectionUtils {public static void main(String[] args) {}@Testpublic void api_01() throws Exception {//得到Class对象Class<?> personCls = Class.forName("Reflection_.Person");// getName:获取全类名System.out.println(personCls.getName());// getSimpleName:获取简单类名System.out.println(personCls.getSimpleName());// getFields:获取所有public修饰的属性,包含父类以及本类的Field[] fields = personCls.getFields();for (Field field : fields) {System.out.println(field);}// getDeclaredFields:获取本类所有属性Field[] declaredFields = personCls.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println("本类所有属性:" + declaredField);}// getMethods:获取所有public修饰的方法,包括本类以及父类的Method[] methods = personCls.getMethods();for (Method method : methods) {System.out.println(method);}// getDeclaredMethods:获取本类所有方法Method[] declaredMethods = personCls.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println("本类所有方法:" + declaredMethod);}// getConstructors: 获取所有public修饰的构造器,包括本类的Constructor<?>[] constructors = personCls.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println(constructor);}// getDeclaredConstructors: 获取本类所有的构造器Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();System.out.println("本类所有构造器:" +declaredConstructors);// getPackage:以Package形式返回包信息System.out.println(personCls.getPackage());// getSuperClass:以Class形式返回父类信息System.out.println(personCls.getSuperclass());// getInterfaces:以Class[]形式返回接口信息Class<?>[] interfaces = personCls.getInterfaces();for (Class<?> anInterface : interfaces) {System.out.println("所有接口信息:" + anInterface);}// getAnnotations:以Annotation[]形式返回注解信息Annotation[] annotations = personCls.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);}}
}
interface B {}
class A {public String hobby;public void hi() {}}
@SuppressWarnings("all")
@Deprecated
class Person extends A implements B{//属性public String name;protected int age;String job;private double sal;//构造器//方法public void m1() {}protected void m2() {}void m3() {}private void m4() {}
}
结果

image-20240114183919690

第二组

image-20240114185417447

代码实例
    @Testpublic void api_02() throws ClassNotFoundException {//得到Class对象Class<?> personCls = Class.forName("Reflection_.Person");Field[] declaredFields = personCls.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println("该类的字段名:" + declaredField.getName() +" 该类的修饰符int形式:" +declaredField.getModifiers() +" 该类的Class类型:" + declaredField.getType());}}
结果

image-20240114185948128

第三组

image-20240114190016983

代码实例
    @Testpublic void api_03() throws ClassNotFoundException {//得到Class对象Class<?> personCls = Class.forName("Reflection_.Person");Method[] declaredMethods = personCls.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println("该类的方法名:" + declaredMethod.getName() +" 该类的方法修饰符int形式:" +declaredMethod.getModifiers() +" 该类的方法返回类型:" + declaredMethod.getReturnType());//获取参数类型数组Class<?>[] parameterTypes = declaredMethod.getParameterTypes();for (Class<?> parameterType : parameterTypes) {System.out.println("参数类型:" + parameterType);}}}
结果

image-20240114190556792

第四组

image-20240114190633447

代码实例
    @Testpublic void api_04() throws ClassNotFoundException {//得到Class对象Class<?> personCls = Class.forName("Reflection_.Person");Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();for (Constructor<?> declaredConstructor : declaredConstructors) {System.out.println("该类的构造器名:" + declaredConstructor.getName() +" 该类的构造器int形式修饰符:" + declaredConstructor.getModifiers());Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();for (Class<?> parameterType : parameterTypes) {System.out.println("参数类型:" + parameterType);}}}
结果

image-20240114191126368

6.反射爆破

1.反射爆破创建实例

image-20240114191310545

代码实例
package Reflection_;import java.lang.reflect.Constructor;/*** @author 孙显圣* @version 1.0*/
public class CreateInstance {public static void main(String[] args) throws Exception {//获取Class类对象Class<?> userClass = Class.forName("Reflection_.User");//1.使用无参构造方法创建实例Object o = userClass.newInstance();System.out.println(o);//2.使用public的有参构造方法创建实例//获取有参构造器对象Constructor<?> constructor = userClass.getConstructor(String.class);//创建实例Object o1 = constructor.newInstance("小明");System.out.println(o1);//3.使用非public的有参构造方法创建实例//获取构造器Constructor<?> declaredConstructor = userClass.getDeclaredConstructor(String.class, int.class);//反射爆破declaredConstructor.setAccessible(true);//创建实例Object o2 = declaredConstructor.newInstance("杰克", 20);System.out.println(o2);}
}
class User {private String name = "李华";private int age = 18;public User() {}public User(String name) {this.name = name;}private User(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}
结果

image-20240114193242314

2.反射爆破操作属性

image-20240114193444582

代码实例
package Reflection_;import java.lang.reflect.Field;/*** @author 孙显圣* @version 1.0*/
public class AccessProperty {public static void main(String[] args) throws Exception {//获取Class实例Class<Student> studentClass = Student.class;//反射创建一个实例Student student = studentClass.newInstance();//1.操作public的属性//获取public的属性Field age = studentClass.getField("age");//操作age.set(student, 100);System.out.println(age.get(student));//2.操作非public且静态的属性//获取私有属性Field name = studentClass.getDeclaredField("name");//反射爆破name.setAccessible(true);//操作name.set(null, "李华");System.out.println(name.get(null)); //注意这里是因为是静态的属性才能填null,如果不是静态的则必须填对象}
}
class Student {public int age;private static String name;@Overridepublic String toString() {return "Student{" +"age=" + age +'}';}
}
结果

image-20240114195123147

3.反射爆破操作方法

image-20240114195340807

代码实例
package Reflection_;import java.lang.reflect.Method;/*** @author 孙显圣* @version 1.0*/
public class AccessMethod {public static void main(String[] args) throws Exception {//获取Class对象Class<Boss> bossClass = Boss.class;//创建实例Boss boss = bossClass.newInstance();//1.操作public的方法//获取方法Method hi = bossClass.getMethod("hi", String.class);//操作hi.invoke(boss, "李华");//2.操作非public的方法//获取方法Method say = bossClass.getDeclaredMethod("say", int.class, String.class, char.class);//爆破say.setAccessible(true);//操作Object invoke = say.invoke(null, 1, "2", '3');//注意,因为这里是静态的方法所以才能是nullSystem.out.println(invoke);}
}class Boss {public int age;private static String name;private static String say(int n, String s, char c) {return n + "" + s + "" + c;}public void hi(String s) {System.out.println("hi:" + s);}
}
结果

image-20240114200437193

7.本章练习

练习一
题目

image-20240114200549768

代码
package Reflection_;import java.lang.reflect.Field;/*** @author 孙显圣* @version 1.0*/
public class HomeWork01 {public static void main(String[] args) throws Exception{//获取Class类Class<PrivateTest> privateTestClass = PrivateTest.class;//创建实例PrivateTest privateTest = privateTestClass.newInstance();//获取属性Field name = privateTestClass.getDeclaredField("name");//反射爆破name.setAccessible(true);//修改属性name.set(privateTest, "cat");//输出属性System.out.println(name.get(privateTest));}
}class PrivateTest {private String name = "hellokitty";public String getName() {return name;}
}
结果

image-20240114201101007

练习二
题目

image-20240114201155350

代码
package Reflection_;import java.io.File;
import java.lang.reflect.Constructor;/*** @author 孙显圣* @version 1.0*/
public class HomeWork02 {public static void main(String[] args) throws Exception{//获取File类的Class对象Class<File> fileClass = File.class;//打印所有构造器Constructor<?>[] declaredConstructors = fileClass.getDeclaredConstructors();for (Constructor<?> declaredConstructor : declaredConstructors) {System.out.println(declaredConstructor);}//获取构造器Constructor<File> declaredConstructor = fileClass.getDeclaredConstructor(String.class);//创建实例File file = declaredConstructor.newInstance("src\\Reflection_\\a.txt");file.createNewFile();}
}
结果

image-20240114201737033

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

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

相关文章

学习刷题-13

3.23 hw机试【二叉树】 剑指offer32 剑指 offer32&#xff08;一、二、三&#xff09;_剑指offer 32-CSDN博客 从上到下打印二叉树I 一棵圣诞树记作根节点为 root 的二叉树&#xff0c;节点值为该位置装饰彩灯的颜色编号。请按照从 左 到 右 的顺序返回每一层彩灯编号。 输…

Spring Cloud Alibaba Sentinel 使用详解

一、Sentinel 介绍 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 Sentinel 具有以下特征: 丰富的应用场景&#xff1a; Sentinel 承接了阿里巴…

微服务(基础篇-003-Nacos集群搭建)

目录 Nacos集群搭建 1.集群结构图 2.搭建集群 2.1.初始化数据库 2.2.下载nacos 2.3.配置Nacos 2.4.启动 2.5.nginx反向代理 2.6.优化 视频地址&#xff1a; 06-Nacos配置管理-nacos集群搭建_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p29&…

Vue字符串里的中文数字转换为阿拉伯数字

js字符串里的汉字数字转化为数字 <template><view><view><view class"inpbox" ><textarea v-model"voiceMane" input"convert" ></textarea></view></view></view> </template> &…

SpringCloudAlibaba之Nacos Config

1、服务配置中心介绍 首先我们来看一下,微服务架构下关于配置文件的一些问题&#xff1a; 配置文件相对分散。在一个微服务架构下&#xff0c;配置文件会随着微服务的增多变的越来越多&#xff0c;而且分散在各个微服务中&#xff0c;不好统一配置和管理。配置文件无法区分环境…

【windows】安装 Tomcat 及配置环境变量

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

Protobuf基础使用

Protobuf是什么 在我们日常编写代码的过程中&#xff0c;经常会涉及到网络传输的部分。我们通常会在网络之间传递各种各样的请求&#xff0c;但是在我们日常架构之中&#xff0c;经常会涉及后端服务器之间的通信&#xff0c;通信过程中&#xff0c;可能传递的对象就是一个类。…

大数据基础:Linux基础详解

课程介绍 本课程主要通过对linux基础课程的详细讲解&#xff0c;让大家熟练虚拟机的安装使用&#xff0c;Linux系统的安装配置&#xff0c;学习掌握linux系统常用命令的使用&#xff0c;常用的软件安装方法&#xff0c;制作快照&#xff0c;克隆&#xff0c;完成免密登录&…

springboot企业级抽奖项目业务三(活动模块)

梅开三度 开发流程 该业务基于rouyi生成好了mapper和service的代码&#xff0c;现在需要在controller层写接口 实际操作流程&#xff1a; 看接口文档一>controller里定义函数一>看给出的工具类一>补全controller里的函数一>运行测试 接口文档 在用户模块用户…

泰迪智能科技荣获山东省“技能兴鲁”职业技能大赛优秀组织奖

近日&#xff0c;泰迪智能科技荣获了山东省“技能兴鲁”职业技能大赛——第四届山东省“云数”技能竞赛“优秀组织单位”。 据悉&#xff0c;山东省“技能兴鲁”职业技能大赛——第四届山东省“云数”技能竞赛是由山东电子学会、山东省信息产业协会主办的&#xff0c;该竞赛是通…

32.HarmonyOS App(JAVA)鸿蒙系统app类自动生成GetSet方法

1.空白区域右键单击 2.选择Generate 3.选择getter,setter 4.选择列出的所有项 5.点击OK 6.成功生成。

说一说Java中的四种引用类型?

引言 在JDK1.2之前Java并没有提供软引用、弱引用和虚引用这些高级的引用类型。而是提供了一种基本的引用类型&#xff0c;称为Reference。并且当时Java中的对象只有两种状态&#xff1a;被引用和未被引用。当一个对象被引用时&#xff0c;它将一直存在于内存中&#xff0c;直到…

Spring Boot 实现定时任务动态管理

前言 本文主要介绍了SpringBoot架构下动态定时任务的使用&#xff0c;定时任务表达式配置在数据库中&#xff0c;通过反射执行到目标方法。 Quartz Quartz 是一个开源的作业调度框架,支持分布式定时任务&#xff0c;Quartz定时任务据我了解可分为Trigger&#xff08;触发器&…

毕业论文降重(gpt+完美降重指令),sci论文降重gpt指令——超级好用,重复率低于4%

1. 降重方法&#xff1a;gpt降重指令 2. gpt网站 https://yiyan.baidu.com/ https://chat.openai.com/ 3. 降重指令——非常好用&#xff01;&#xff01;sci论文&#xff0c;本硕大论文都可使用&#xff01; 请帮我把下面句子重新组织&#xff0c;通过调整句子逻辑&#xff0…

nvidia显卡如何安装cuda驱动

目录 查看显卡对应的cuda版本下载与你显卡匹配的CUDA Toolkit 查看显卡对应的cuda版本 按 微软 R 键&#xff0c;输入cmd 然后输入 nvidia-smi &#xff0c;回车显示下面信息&#xff1a; 看到 CUDA Version 为 12.2 下载与你显卡匹配的CUDA Toolkit 打开网页&#xff1a…

【项目管理——时间管理】【自用笔记】

1 项目时间管理&#xff08;进度管理&#xff09;概述 过程&#xff1a;&#xff08;2—6&#xff09;为规划过程组&#xff0c;7为监控过程组 题目定义&#xff1a;项目时间管理又称为进度管理&#xff0c;是指确保项目按时完成所需的过程。目标&#xff1a;时间管理的主要目标…

疲劳检测YOLOV8

疲劳检测YOLOV8&#xff0c;只需要OPENCV&#xff0c;采用YOLOV8训练得到PT模型&#xff0c;然后转换成ONNX&#xff0c;OPENCV调用&#xff0c;支持C/PYTHON/ANDROID开发疲劳检测YOLOV8

嵌入式开发--获取STM32产品系列的信息

嵌入式开发–获取STM32产品系列和容量信息 获取STM32产品系列 有时候我们需要知道当前MCU是STM32的哪一个系列&#xff0c;这当然可以从外部丝印看出来&#xff0c;但是运行在内部的软件如何知道呢&#xff1f; ST为我们提供了一个接口&#xff0c;F1和G4系列地址统一为&…

第十四届蓝桥杯省赛C++ A组所有题目以及题解(C++)【编程题均通过100%测试数据】

第一题《幸运数》【模拟】 【问题描述】 小蓝认为如果一个数含有偶数个数位&#xff0c;并且前面一半的数位之和等于后面一半的数位之和&#xff0c;则这个数是他的幸运数字。例如 2314是一个幸运数字,因为它有4个数位,并且2314。现在请你帮他计算从1至100000000之间共有多少…

李国武:如何评估一家精益制造咨询公司的实施能力?

在制造业转型升级的大背景下&#xff0c;精益制造已成为企业提升竞争力、实现可持续发展的关键。然而&#xff0c;面对市场上众多的精益制造咨询公司&#xff0c;如何评估其实施能力成为了众多企业的难题。本文将从多个方面为大家揭示评估精益制造咨询公司实施能力的方法&#…