首页/新闻资讯/正文详情

枚举、反射

发布时间:2026/9/24 13:53:35 来源:云帆数科 栏目:资讯中心
枚举、反射
一、 枚举1.1 枚举的概述枚举是 Java 中一种特殊的类它可以定义固定数量的枚举实例例如: 性别、交通信号灯、季节等等1.2 为什么要使用枚举假设我们要定义一个人类人类中包含姓名和性别。通常会将性别定义成字符串类型不使用枚举存在的问题可以给性别传入任意的字符串导致性别是非法的数据不安全。解决固定数量的实例即一个方法接受的参数是固定范围之内的时候那么即可使用枚举类型1.3 格式enum 枚举名 {第一行都是罗列枚举实例,这些枚举实例直接写大写名字即可。}1.4 案例1.定义枚举enum Aimal { Cat, Dog, Zi; }2.将A中的String类型改为type枚举类型public class A { public Aimal b; }3.使用是只能传入枚举中的固定值Test public void creat(){ A anew A(); a.bB.Cat; System.out.println(a.b); }枚举中添加成员变量和成员方法枚举的本质是一个类所以枚举中还可以有成员变量成员方法等。enum Aimal { Cat(猫), Dog(狗), Zi(猪); private String s; Aimal(String s) { this.ss; System.out.println(); } public String getS() { return s; } }Test public void creat(){ A anew A(); a.bAimal.Cat; System.out.println(a.b.getS()); }二、反射2.1 类加载类在内存中的生命周期加载--使用--卸载2.1.1类加载过程当程序主动使用某个类时如果该类还未被加载到内存中系统会通过加载、连接、初始化三个步骤来对该类进行初始化如果没有意外JVM将会连续完成这三个步骤所以有时也把这三个步骤统称为类加载。三个阶段1加载load就是指将类型的class字节码数据读入内存2连接link①验证校验合法性等②准备准备对应的内存方法区创建Class对象为类变量赋默认值为静态常量赋初始值。③解析把字节码中的符号引用替换为对应的直接地址引用3初始化initialize类初始化即执行clinit类初始化方法会给类的静态变量赋初始值2.1.2 类初始化1运行主方法所在的类要先完成类初始化再执行main方法public class C { static { System.out.println(执行C); } //运行主方法所在的类要先完成类初始化再执行main方法 public static void main(String[] args) { } }2第一次使用某个类型就是在new它的对象此时这个类没有初始化的话先完成类初始化再做实例初始化public class C { /* 第一次使用某个类型就是在new它的对象 此时这个类没有初始化的话 先完成类初始化再做实例初始化*/ public static void main(String[] args) { new A(); } } public class A { static { System.out.println(执行A); } }3调用某个类的静态成员类变量和类方法此时这个类没有初始化的话先完成类初始化public class C { /* 调用某个类的静态成员类变量和类方法 此时这个类没有初始化的话 先完成类初始化*/ public static void main(String[] args) { System.out.println(A.s); } } public class A { public static int s20; static { System.out.println(执行A); } }4子类初始化时发现它的父类还没有初始化的话那么先初始化父类class D{ static { System.out.println(执行A); } } public class C extends D{ static { System.out.println(执行c); } /* 子类初始化时 发现它的父类还没有初始化的话 那么先初始化父类*/ public static void main(String[] args) { new C(); } }5通过反射操作某个类时如果这个类没有初始化也会导致该类先初始化**注意什么情况下类不会被加载到内存中①、访问静态常量class D{ public static final int s10; static { System.out.println(执行A); } } public class C { /* 访问静态常量 类不会被加载到内存中 */ public static void main(String[] args) { System.out.println(D.s); } }②、通过子类去调用父类的静态资源(子类不会被加载、父类会被加载)public class A { public static int s10; public static void setS(){ } static { System.out.println(执行A); } }class E extends A{ static { System.out.println(执行E); } } public class C { /* 通过子类去调用父类的静态资源(子类不会被加载、父类会被加载) */ public static void main(String[] args) { E.setS(); } }③、使用对应类型数组(该类不会被加载)class D{ public static final int s10; static { System.out.println(执行A); } } public class C { /* 使用对应类型数组(该类不会被加载) */ public static void main(String[] args) { D[] ds new D[10]; } }2.1.3 类加载器想要更好的解决java.lang.ClassNotFoundException或java.lang.NoClassDefError 这类问题类加载器分为:1引导类加载器Bootstrap Classloader又称为根类加载器它负责加载jre/lib中的核心库它本身不是Java代码实现的也不是ClassLoader的子类获取它的对象时往往返回null2扩展类加载器Extension ClassLoader它负责加载jre/lib/ext扩展库它是ClassLoader的子类3应用程序类加载器Application Classloader它负责加载项目的classpath路径下的类它是ClassLoader的子类4自定义类加载器当你的程序需要加载“特定”目录下的类可以自定义类加载器当你的程序的字节码文件需要加密时那么往往会提供一个自定义类加载器对其进行解码后面会见到的自定义类加载器tomcat中2.1.4 类加载器的双亲委托模式原理: 加载字节码文件时先由下至上(当前类加载器是否加载过没有则找上一层是否加载过)都没有加载则由上至下尝试进行加载都没有加载到则报错2.2java.lang.Class类2.2.1 概念Java反射机制是在运行状态中对于任意一个类都能够知道这个类的所有属性和方法对于任意一个对象都能够调用它的任意一个方法和属性这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。字节码文件.Class①、创建对象②、了解该类属于那个父类、实现了那些接口...③、知道该类有那些成员变量、成员方法④、操作成员变量、调用成员方法目的: 程序灵活、可扩展性更强2.2.2 获取Class对象的四种方式1类型名.class要求编译期间已知类型2对象.getClass()获取对象的运行时类型3Class.forName(类型全名称)通常需要配置文件配置配合使用可以获取编译期间未知的类型4ClassLoader的类加载器对象.loadClass(类型全名称)可以用系统类加载对象或自定义加载器对象加载指定路径下的类型//获取Class对象的四种方式 //第一种方式获取Class: 类型名.class ClassB bClass B.class; //第二种方式获取Class: 对象.getClass() B b new B(); Class? extends B aClass b.getClass(); //第三种方式获取Class: Class.forName(类的全限定名) Class? aClass1 Class.forName(reflex.TestReflex);*/ ClassD dClass D.class;2.3反射概念反射是一种机制/功能利用该机制/功能可以在程序运行过程中对类进行解剖并操作类中的构造方法成员方法成员属性。2.4反射的应用2.4.1 获取类型的详细信息可以获取包、修饰符、类型名、父类包括泛型父类、父接口包括泛型父接口、成员属性、构造器、方法、注解类上的、方法上的、属性上的2.4.1.1 获取包信息Package pkg clazz.getPackage();2.4.1.2 获取修饰符int mod clazz.getModifiers();修饰符定义在Modifier类中该类里面有很多常量值每一个常量对应一种修饰符2.4.1.3 获取类名String name clazz.getName();2.4.1.4 获取父类的字节码对象Class superclass clazz.getSuperclass();2.4.1.5 获取该类实现的所有接口Class[] interfaces clazz.getInterfaces();2.4.1.6 获取该类的所有属性Field[] declaredFields clazz.getDeclaredFields();2.4.1.7 获取该类的所有构造函数Method[] declaredConstructors clazz.getDeclaredConstructors();2.4.1.8 获取该类的所有方法Method[] declaredMethods clazz.getDeclaredMethods();2.4.2 创建任意引用类型的对象(重点)两种方式1、直接通过Class对象来实例化要求必须有无参构造2、通过获取构造器对象来进行实例化package reflect; public class D { private String id; private String name; private Integer age; private D(String id, String name, Integer age) { this.id id; this.name name; this.age age; } public D() { } public String getId() { return id; } public void setId(String id) { this.id id; } public String getName() { return name; } public void setName(String name) { this.name name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age age; } Override public String toString() { return D{ id id \ , name name \ , age age }; } private void showMsg(String name){ System.out.println(name name); } }方式一的步骤1获取该类型的Class对象2创建对象ClassD dClass D.class; // 创建对象 (使用字节码文件newInstance创建对象时使用无参数的构造函数) D d dClass.newInstance(); System.out.println(d);方式二的步骤ConstructorT getConstructor(Class?... parameterTypes) 返回一个 Constructor对象该对象反映 Constructor对象表示的类的指定的公共类函数。 Constructor?[] getConstructors() 返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。 ConstructorT getDeclaredConstructor(Class?... parameterTypes) 返回一个 Constructor对象该对象反映 Constructor对象表示的类或接口的指定类函数。 Constructor?[] getDeclaredConstructors() 返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类 。1获取该类型的Class对象2获取构造器对象3创建对象ClassD dClass D.class; ConstructorD constructor dClass.getDeclaredConstructor(String.class, String.class, Integer.class); constructor.setAccessible(true); D ss constructor.newInstance(10012, ss, 18); System.out.println(ss);2.3.3 操作任意类型的属性(重点)反射操作字段 ①、获取字节码对象 ②、获取字段(成员变量)对象 Field getDeclaredField(String name) 返回一个 Field对象它反映此表示的类或接口的指定已声明字段 类对象。 Field[] getDeclaredFields() 返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。 Field getField(String name) 返回一个 Field对象它反映此表示的类或接口的指定公共成员字段 类对象。 Field[] getFields() 返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象 ③、给字段取值、赋值 Object get(Object obj) void set(Object obj, Object value)1获取该类型的Class对象ClassD dClass D.class;2获取属性对象Field id dClass.getDeclaredField(id); Field name dClass.getDeclaredField(name); Field age dClass.getDeclaredField(age);3设置属性可访问id.setAccessible(true); name.setAccessible(true); age.setAccessible(true);4创建实例对象如果操作的是非静态属性需要创建实例对象D d dClass.newInstance();4设置属性值id.set(d,1003); name.set(d,王琪); age.set(d,20);5获取属性值System.out.println(id.get(d)); System.out.println(name.get(d)); System.out.println(age.get(d));System.out.println(d);如果操作静态变量那么实例对象可以省略用null表示当然一般不会使用反射操作静态变量Test public void invokeFiled() throws NoSuchFieldException, InstantiationException, IllegalAccessException { ClassD dClass D.class; Field id dClass.getDeclaredField(id); Field name dClass.getDeclaredField(name); Field age dClass.getDeclaredField(age); D d dClass.newInstance(); id.setAccessible(true); id.set(d,1003); name.setAccessible(true); name.set(d,王琪); age.setAccessible(true); age.set(d,20); System.out.println(id.get(d)); System.out.println(name.get(d)); System.out.println(age.get(d)); System.out.println(d); System.out.println(); Field[] fields dClass.getDeclaredFields(); Arrays.stream(fields) .forEach(f-{ System.out.println(f.getName():f.getModifiers()); }); }2.4.4 调用任意类型的方法反射调用方法 ①、获取字节码对象 ②、获取字节码对象中的方法对象 Method getDeclaredMethod(String name, Class?... parameterTypes) 返回一个 方法对象它反映此表示的类或接口的指定声明的方法 类对象。 Method[] getDeclaredMethods() 返回包含一个数组 方法对象反射的类或接口的所有声明的方法通过此表示 类对象包括公共保护默认包访问和私有方法但不包括继承的方法。 Method getMethod(String name, Class?... parameterTypes) 返回一个 方法对象它反映此表示的类或接口的指定公共成员方法 类对象。 Method[] getMethods() 返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象包括那些由类或接口和那些从超类和超接口继承的声明。 ③、调用方法 Object invoke(Object obj, Object... args) 在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。1获取该类型的Class对象ClassD dClass D.class;2获取方法对象Method showMsg dClass.getDeclaredMethod(showMsg, String.class);3创建实例对象D d dClass.newInstance();4调用方法Object zs showMsg.invoke(d, zs); System.out.println(zs);如果方法的权限修饰符修饰的范围不可见也可以调用setAccessible(true)如果方法是静态方法实例对象也可以省略用null代替Test public void invokeMethod() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { ClassD dClass D.class; Method showMsg dClass.getDeclaredMethod(showMsg, String.class); D d dClass.newInstance(); showMsg.setAccessible(true); Object zs showMsg.invoke(d, zs); System.out.println(zs); System.out.println(); Method[] methods dClass.getMethods(); Arrays.stream(methods) .forEach(e-{ System.out.println(e.getName()-Arrays.toString(e.getParameterTypes())); }); }

相关推荐

QzoneArchive完整指南:5分钟把QQ空间动态、照片、视频安全归档到本地
QzoneArchive完整指南:5分钟把QQ空间动态、照片、视频安全归档到本地

QzoneArchive完整指南:5分钟把QQ空间动态、照片、视频安全归档到本地 【免费下载链接】QzoneArchive 将 QQ 空间历史动态、照片、视频与互动记录安全归档到本地的桌面 / 移动端工具。 项目地址: https://gitcode.com/gh_mirrors/qz/QzoneArchive QzoneArchiv… · 2026/9/24 13:53:35

网络编程介绍
网络编程介绍

指在计算机网络中怎样实现数据传输 软件结构: C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、红蜘蛛、飞秋等软件。 B/S结构 :全称为Browser/Server结构,是指浏览… · 2026/9/24 13:53:35

单片机毕设选题推荐:基于 STM32 的多环境参数采集及微信小程序远程管控系统 基于 STM32 的室内空气质量检测与声光报警硬件系统设计(010309)
单片机毕设选题推荐:基于 STM32 的多环境参数采集及微信小程序远程管控系统 基于 STM32 的室内空气质量检测与声光报警硬件系统设计(010309)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️… · 2026/9/24 13:53:35

深度学习新闻分类推荐系统:从TextCNN到个性化推荐
深度学习新闻分类推荐系统:从TextCNN到个性化推荐

简介:这份基于深度学习的新闻分类推荐系统Python实现源码,是专为课程设计与期末大作业准备的高分项目,下载后无需修改即可运行,适用于需要快速交付完整课题的高校学生。系统涵盖新闻数据预处理、文本分类模型训练、推荐逻辑展示等… · 2026/9/24 23:59:53

汽车电子底层软件开发:AUTOSAR与CAN总线实战解析
汽车电子底层软件开发:AUTOSAR与CAN总线实战解析

1. 这门“汽车电子底层软件开发就业课”到底在教什么?——不是写个LED闪烁就能上岗的很多人看到“汽车电子底层软件开发就业课”这个标题,第一反应是:不就是嵌入式C语言单片机CAN通信?刷几道LeetCode、调通一个STM32 CAN收发例程&… · 2026/9/24 23:59:53

Vim基础操作全攻略:保存退出、模式切换与高频命令实战
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保… · 2026/9/24 23:59:53

Python+CNN车牌识别实战:从数据预处理到模型训练与部署
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据… · 2026/9/24 23:59:53

AI元人文:从工具使用到思维重构的深度探索
AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决… · 2026/9/24 23:59:53

《AI Agent 场景应用 - MobileOpenClaw》第5-9节:会话上下文细化处理实战指南
《AI Agent 场景应用 - MobileOpenClaw》第5-9节:会话上下文细化处理实战指南

文档教程后端 【免费下载链接】CodeGuide :books: 本代码库是作者小傅哥多年从事一线互联网 Java 开发的学习历程技术汇总,旨在为大家提供一个清晰详细的学习教程,侧重点更倾向编写Java核心内容。如果本仓库能为您提供帮助,请给予支持(关注、… · 2026/9/24 23:59:47

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码