news 2026/5/9 14:49:01

Java基础十六:枚举,包,反射

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java基础十六:枚举,包,反射

一、枚举(Enum)

1. 什么是枚举

枚举是一种特殊的类,用于定义一组固定的常量。

2. 基本用法

// 最简单的枚举 public enum Season { SPRING, SUMMER, AUTUMN, WINTER } // 使用枚举 public class TestEnum { public static void main(String[] args) { Season s = Season.SPRING; // 常用方法 System.out.println(s.name()); // SPRING System.out.println(s.ordinal()); // 0(索引位置) System.out.println(s.toString()); // SPRING // 遍历枚举 for (Season season : Season.values()) { System.out.println(season); } // 根据字符串获取枚举 Season autumn = Season.valueOf("AUTUMN"); // switch 中使用枚举 switch (s) { case SPRING: System.out.println("春天"); break; case SUMMER: System.out.println("夏天"); break; default: System.out.println("其他季节"); } } }

3. 带属性和方法的枚举

public enum Grade { // 枚举常量必须首先定义,可以带参数 EXCELLENT("优秀", 90, 100) { @Override public String getDescription() { return "成绩优异,表现突出"; } }, GOOD("良好", 80, 89) { @Override public String getDescription() { return "成绩良好,继续保持"; } }, PASS("及格", 60, 79) { @Override public String getDescription() { return "成绩及格,需要努力"; } }, FAIL("不及格", 0, 59) { @Override public String getDescription() { return "成绩不及格,需要补习"; } }; // 成员变量 private String chineseName; private int minScore; private int maxScore; // 构造方法(必须是 private) private Grade(String chineseName, int minScore, int maxScore) { this.chineseName = chineseName; this.minScore = minScore; this.maxScore = maxScore; } // 普通方法 public String getChineseName() { return chineseName; } public boolean isInRange(int score) { return score >= minScore && score <= maxScore; } // 抽象方法(每个枚举常量必须实现) public abstract String getDescription(); // 静态方法 public static Grade fromScore(int score) { for (Grade grade : Grade.values()) { if (grade.isInRange(score)) { return grade; } } return FAIL; } } // 使用示例 public class TestGrade { public static void main(String[] args) { int score = 85; Grade grade = Grade.fromScore(score); System.out.println("分数:" + score); System.out.println("等级:" + grade); System.out.println("中文名:" + grade.getChineseName()); System.out.println("描述:" + grade.getDescription()); // 输出: // 分数:85 // 等级:GOOD // 中文名:良好 // 描述:成绩良好,继续保持 } }

4. 枚举实现接口

interface Describable { String describe(); } enum Color implements Describable { RED { @Override public String describe() { return "热情奔放的红色"; } }, GREEN { @Override public String describe() { return "生机勃勃的绿色"; } }, BLUE { @Override public String describe() { return "宁静深邃的蓝色"; } }; // 也可以在枚举级别实现 // @Override // public String describe() { // return "这是一个颜色"; // } }

二、包(Package)

1. 什么是包

包用于组织类和接口,类似于文件系统中的文件夹,避免命名冲突,提供访问保护。

2. 包的定义和使用

// 文件:com/example/model/User.java package com.example.model; // 必须在第一行(注释除外) import java.util.Date; // 导入单个类 import java.util.*; // 导入包下所有类 import static java.lang.Math.PI; // 静态导入 public class User { private String name; private Date birthday; public double getCircleArea(double radius) { return PI * radius * radius; // 直接使用静态导入的常量 } }

3. 包命名规范

// 包名全部小写,使用域名倒序 // 常见包结构: com.example.project.model // 数据模型 com.example.project.dao // 数据访问层 com.example.project.service // 业务逻辑层 com.example.project.controller // 控制器层 com.example.project.util // 工具类 com.example.project.exception // 异常类 com.example.project.config // 配置类

4. 包的访问权限

// 文件:com/example/Person.java package com.example; public class Person { public String name; // 任何地方都能访问 protected int age; // 子类和同包可以访问 String address; // 默认权限:同包可以访问 private String idCard; // 只有本类能访问 } // 文件:com/example/Test.java(同包) package com.example; public class Test { public static void main(String[] args) { Person p = new Person(); p.name = "张三"; // ✅ public p.age = 18; // ✅ protected(同包) p.address = "北京"; // ✅ default(同包) // p.idCard = "xxx"; // ❌ private,无法访问 } }

5. 包和编译运行

# 目录结构 # src/ # com/ # example/ # Hello.java # 编译 javac -d . src/com/example/Hello.java # 运行 java com.example.Hello # 打包成jar jar cvf myapp.jar com/

三、反射(Reflection)

1. 什么是反射

反射允许程序在运行时获取类的完整信息,并动态地操作类的属性和方法

2. 获取Class对象的三种方式

通俗理解:把类想象成一个设计图纸(比如person类的代码),吧Class对象想象成这个图纸的说明书,通过说明书可以知道图纸上画了什么,有什么属性,能做什么事。

// 方式1:通过类名.class Class<?> clazz1 = String.class; //适用场景 // 示例:获取任意已知类的 Class 对象 Class<?> clazz1 = Person.class; Class<?> clazz2 = ArrayList.class; Class<?> clazz3 = int.class; // 基本类型也可以 // 方式2:通过对象.getClass() String str = "hello"; Class<?> clazz2 = str.getClass(); //适用场景:手头上有了一个对象,想知道它属于哪一类 // 示例:多态情况下的实际类型 Animal animal = new Dog(); // 声明为 Animal,实际是 Dog Class<?> clazz = animal.getClass(); // 返回的是 Dog.class,不是 Animal.class // 判断对象的实际类型 if (animal.getClass() == Dog.class) { System.out.println("这实际上是一条狗"); } // 方式3:通过 Class.forName() Class<?> clazz3 = Class.forName("java.lang.String"); //适用场景:不知道具体类名,需要动态配置 public class Demo { public static void main(String[] args) throws Exception { // 1. 类名.class - 静态方式 Class<?> clazz1 = User.class; System.out.println("方式1:" + clazz1.getName()); // 2. 对象.getClass() - 已有对象 User user = new User("张三", 20); Class<?> clazz2 = user.getClass(); System.out.println("方式2:" + clazz2.getName()); // 3. Class.forName() - 动态加载 String className = "com.example.User"; // 可以从配置文件读取 Class<?> clazz3 = Class.forName(className); System.out.println("方式3:" + clazz3.getName()); // 三种方式获取的是同一个 Class 对象 System.out.println(clazz1 == clazz2); // true System.out.println(clazz1 == clazz3); // true } } class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } }

3.获取类的信息

public class ReflectionDemo { public static void main(String[] args) throws Exception { Class<?> clazz = Person.class; // 获取类名 System.out.println("类名:" + clazz.getName()); System.out.println("简单类名:" + clazz.getSimpleName()); // 获取包信息 Package pkg = clazz.getPackage(); System.out.println("包名:" + pkg.getName()); // 获取修饰符 int modifiers = clazz.getModifiers(); System.out.println("是否是public:" + Modifier.isPublic(modifiers)); // 获取父类 Class<?> superclass = clazz.getSuperclass(); System.out.println("父类:" + superclass.getName()); // 获取接口 Class<?>[] interfaces = clazz.getInterfaces(); // 获取构造方法 Constructor<?>[] constructors = clazz.getConstructors(); // 获取方法 Method[] methods = clazz.getDeclaredMethods(); // 获取字段 Field[] fields = clazz.getDeclaredFields(); } }

4.动态创建对象

// 方式1:通过 Class 对象 Class<?> clazz = Person.class; Person person1 = (Person) clazz.newInstance(); // 已废弃 // 方式2:通过 Constructor(推荐) Constructor<Person> constructor = Person.class.getConstructor(String.class, int.class); Person person2 = constructor.newInstance("张三", 20); // 创建数组 Object array = Array.newInstance(String.class, 10); Array.set(array, 0, "hello"); String value = (String) Array.get(array, 0);

5.动态调用方法

public class MethodInvokeDemo { public static void main(String[] args) throws Exception { Person person = new Person("李四", 25); Class<?> clazz = person.getClass(); // 获取并调用公有方法 Method publicMethod = clazz.getMethod("getName"); String name = (String) publicMethod.invoke(person); System.out.println(name); // 获取并调用私有方法 Method privateMethod = clazz.getDeclaredMethod("privateMethod", String.class); privateMethod.setAccessible(true); // 突破私有权限 String result = (String) privateMethod.invoke(person, "参数"); // 调用静态方法 Method staticMethod = clazz.getMethod("staticMethod"); staticMethod.invoke(null); // 静态方法不需要对象实例 } } class Person { private String name; private int age; public Person() {} public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } private String privateMethod(String param) { return "私有方法:" + param; } public static void staticMethod() { System.out.println("静态方法"); } }

6.动态操作字段

Person person = new Person("王五", 30); Class<?> clazz = person.getClass(); // 获取私有字段 Field nameField = clazz.getDeclaredField("name"); nameField.setAccessible(true); // 突破私有权限 // 读取字段值 String name = (String) nameField.get(person); System.out.println("原值:" + name); // 修改字段值 nameField.set(person, "赵六"); System.out.println("新值:" + nameField.get(person));
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 14:48:32

Claude Code用户如何配置Taotoken解决访问不稳定与额度不足问题

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 Claude Code用户如何配置Taotoken解决访问不稳定与额度不足问题 应用场景类&#xff0c;针对频繁使用Claude Code进行编程辅助但受…

作者头像 李华
网站建设 2026/5/9 14:44:12

AI赋能机器人柔顺控制:从经典阻抗到强化学习实战

1. 项目概述&#xff1a;当机器人学会“以柔克刚” 在工业机器人领域&#xff0c;让机械臂像人手一样灵巧地完成装配、打磨、抛光等需要与环境发生物理接触的任务&#xff0c;一直是个核心挑战。想象一下&#xff0c;你要把一个方形的乐高积木严丝合缝地按进底座&#xff0c;或…

作者头像 李华
网站建设 2026/5/9 14:43:32

CANN ops-nn Mish激活函数API

aclnnMish&aclnnInplaceMish 【免费下载链接】ops-nn 本项目是CANN提供的神经网络类计算算子库&#xff0c;实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-nn &#x1f4c4; 查看源码 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DT√…

作者头像 李华
网站建设 2026/5/9 14:38:39

AirPodsDesktop深度解析:打破生态壁垒的Windows音频革命

AirPodsDesktop深度解析&#xff1a;打破生态壁垒的Windows音频革命 【免费下载链接】AirPodsDesktop ☄️ AirPods desktop user experience enhancement program, for Windows and Linux (WIP) 项目地址: https://gitcode.com/gh_mirrors/ai/AirPodsDesktop AirPodsDe…

作者头像 李华
网站建设 2026/5/9 14:38:38

生成式AI驱动模拟电路设计:CktGen框架原理与实践指南

1. 项目概述&#xff1a;当AI开始“画”电路作为一名在模拟电路设计领域摸爬滚打了十几年的工程师&#xff0c;我经历过无数次从零开始绘制电路图的“痛苦”过程。从确定架构、手算参数、到EDA工具里一个晶体管一个晶体管地摆放、连线、仿真、调参&#xff0c;再到版图绘制和物…

作者头像 李华
网站建设 2026/5/9 14:35:12

3步极速获取百度网盘提取码:免费智能工具终极指南

3步极速获取百度网盘提取码&#xff1a;免费智能工具终极指南 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 还在为百度网盘提取码而烦恼吗&#xff1f;baidupankey作为一款专业的百度网盘提取码智能获取工具&#xff0c;彻底…

作者头像 李华