Java 基本语法详解(七)

AI的出现,是否能替代IT从业者? 10w+人浏览 1.6k人参与

Java 基本语法详解(七)

十八、枚举(Enum)基础

枚举是 Java 5 引入的特殊数据类型,用于定义 “固定且有限的一组常量”(如季节、星期、状态码),相比用static final常量,枚举更具类型安全性、可读性和可扩展性。

1. 枚举的核心优势

  • 类型安全:枚举常量是唯一的,避免传入无效值(如用1表示 “成功”,误传5会导致逻辑错误,而枚举仅允许指定常量);

  • 可读性强:直接用常量名表示含义(如Season.SPRING比1更易理解);

  • 内置方法:枚举类自动继承java.lang.Enum,提供name()、ordinal()等实用方法,无需手动实现。

2. 枚举的定义与使用

(1)基本枚举定义(无属性和方法)

格式:enum 枚举名 { 常量1, 常量2, 常量3; }(常量名需全大写,多个常量用逗号分隔,末尾可加分号)。

示例:定义 “季节” 枚举

// 定义枚举类
enum Season {
    SPRING, SUMMER, AUTUMN, WINTER; // 季节常量(固定4个)
}

// 使用枚举
public class EnumBasicDemo {
    public static void main(String[] args) {
        // 1. 直接使用枚举常量
        Season currentSeason = Season.SPRING;
        System.out.println("当前季节:" + currentSeason); // 输出:当前季节:SPRING

        // 2. 枚举的内置方法
        System.out.println("枚举常量名:" + currentSeason.name()); // 输出:枚举常量名:SPRING
        System.out.println("枚举常量索引(从0开始):" + currentSeason.ordinal()); // 输出:枚举常量索引(从0开始):0

        // 3. 遍历所有枚举常量(values()方法:返回枚举数组)
        System.out.print("所有季节:");
        for (Season season : Season.values()) {
            System.out.print(season + " "); // 输出:所有季节:SPRING SUMMER AUTUMN WINTER 
        }

        // 4. 枚举比较(直接用==,无需equals())
        if (currentSeason == Season.SPRING) {
            System.out.println("\n当前是春季,适合踏青!"); // 输出:当前是春季,适合踏青!
        }
    }
}
(2)带属性和方法的枚举(增强版)

枚举本质是 “特殊的类”,可包含成员变量、构造方法和成员方法,实现更复杂的逻辑(如给每个常量绑定额外信息)。

示例:定义 “订单状态” 枚举(含状态码和描述)

// 带属性和方法的枚举
enum OrderStatus {
    // 枚举常量:需匹配构造方法参数(顺序:状态码,描述)
    PENDING(100, "待支付"),
    PAID(200, "已支付"),
    SHIPPED(300, "已发货"),
    DELIVERED(400, "已送达"),
    CANCELLED(500, "已取消");

    // 成员变量(枚举的属性)
    private final int code;    // 状态码(final:初始化后不可修改)
    private final String desc; // 状态描述

    // 构造方法(枚举构造方法必须是private,且只能在枚举内部调用)
    private OrderStatus(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    // 成员方法(获取属性值)
    public int getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }

    // 自定义方法:根据状态码获取枚举常量
    public static OrderStatus getByCode(int code) {
        for (OrderStatus status : OrderStatus.values()) {
            if (status.getCode() == code) {
                return status;
            }
        }
        throw new IllegalArgumentException("无效的订单状态码:" + code); // 无匹配时抛异常
    }
}

// 使用带属性的枚举
public class EnumAdvancedDemo {
    public static void main(String[] args) {
        // 1. 获取枚举常量的属性
        OrderStatus status = OrderStatus.PAID;
        System.out.println("订单状态:" + status); // 输出:订单状态:PAID
        System.out.println("状态码:" + status.getCode()); // 输出:状态码:200
        System.out.println("状态描述:" + status.getDesc()); // 输出:状态描述:已支付

        // 2. 调用自定义方法(根据状态码获取枚举)
        OrderStatus statusByCode = OrderStatus.getByCode(300);
        System.out.println("状态码300对应的状态:" + statusByCode.getDesc()); // 输出:状态码300对应的状态:已发货

        // 3. 模拟订单状态流转
        OrderStatus orderStatus = OrderStatus.PENDING;
        System.out.println("\n初始订单状态:" + orderStatus.getDesc());
        
        orderStatus = OrderStatus.PAID;
        System.out.println("用户支付后状态:" + orderStatus.getDesc());
        
        orderStatus = OrderStatus.SHIPPED;
        System.out.println("商家发货后状态:" + orderStatus.getDesc());
    }
}

输出结果

订单状态:PAID
状态码:200
状态描述:已支付
状态码300对应的状态:已发货

初始订单状态:待支付
用户支付后状态:已支付
商家发货后状态:已发货

十九、注解(Annotation)基础

注解(也称 “标注”)是 Java 5 引入的特殊语法,用于 “为代码添加元数据”(如说明方法功能、标记类的用途),不直接影响代码逻辑,但可被编译器、框架(如 Spring)或工具解析,实现自动化处理(如自动生成代码、参数校验)。

1. 注解的核心作用

  • 编译器提示:如@Override标记方法重写,编译器会校验是否符合重写规则;

  • 框架配置:如 Spring 的@Component标记类为 “组件”,框架自动扫描并创建对象;

  • 代码分析:如@Deprecated标记 “过时” 方法,IDE 会提示开发者避免使用;

  • 自定义逻辑:通过自定义注解 + 解析器,实现个性化需求(如参数校验、日志记录)。

2. Java 内置注解(常用)

Java 提供了 3 个核心内置注解,直接用于代码标记:

注解名作用描述
@Override标记方法是 “重写父类的方法”,编译器会校验:方法名、参数列表、返回值是否与父类一致
@Deprecated标记 “过时” 的类 / 方法 / 字段,提示开发者该元素已不推荐使用,存在更好的替代方案
@SuppressWarnings抑制编译器产生的 “警告信息”(如未使用变量警告、未检查类型转换警告),需指定警告类型
示例:内置注解的使用
public class BuiltInAnnotationDemo {
    public static void main(String[] args) {
        // 调用过时方法(IDE会提示警告)
        OldUtils.oldMethod();

        // 抑制“未使用变量”警告
        @SuppressWarnings("unused")
        String unusedVar = "这是未使用的变量";

        // 创建子类对象并调用重写方法
        Animal dog = new Dog();
        dog.makeSound();
    }
}

// 父类
class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
}

// 子类:@Override标记方法重写
class Dog extends Animal {
    // @Override:若方法名写错(如makeSound1),编译器会报错
    @Override
    public void makeSound() {
        System.out.println("小狗汪汪叫");
    }
}

// 过时工具类:@Deprecated标记
class OldUtils {
    // 标记方法过时,并说明替代方案
    @Deprecated(since = "1.0", forRemoval = true, message = "请使用NewUtils.newMethod()替代")
    public static void oldMethod() {
        System.out.println("这是过时的方法,不推荐使用!");
    }
}

// 新工具类(替代OldUtils)
class NewUtils {
    public static void newMethod() {
        System.out.println("这是新方法,推荐使用!");
    }
}

说明

  • @Deprecated的属性:since表示 “从哪个版本开始过时”,forRemoval表示 “未来是否会删除”,message表示 “提示信息”;

  • @SuppressWarnings的警告类型:unused抑制 “未使用变量” 警告,rawtypes抑制 “未指定泛型” 警告,all抑制所有警告(不推荐)。

3. 自定义注解(基础)

除了内置注解,还可自定义注解,实现特定业务逻辑(需结合 “元注解” 和 “解析器”)。

(1)自定义注解的格式

自定义注解需用@interface声明,且必须搭配 “元注解”(描述注解本身的注解),常用元注解:

元注解名作用描述
@Target指定注解可作用的 “目标元素”(如类、方法、字段),取值:TYPE(类)、METHOD(方法)、FIELD(字段)等
@Retention指定注解的 “保留周期”,取值:SOURCE(仅源码)、CLASS(源码 + 字节码)、RUNTIME(源码 + 字节码 + 运行时,可通过反射解析)
@Documented标记注解是否会被javadoc工具生成到 API 文档中
@Inherited标记注解是否会被 “子类继承”(仅作用于类级别的注解)
示例:自定义 “日志注解”(标记需要打印日志的方法)
import java.lang.annotation.*;

// 1. 自定义注解(@Log:标记方法需打印日志)
@Target(ElementType.METHOD) // 注解仅作用于“方法”
@Retention(RetentionPolicy.RUNTIME) // 保留到运行时,支持反射解析
@Documented // 生成API文档时包含该注解
public @interface Log {
    // 注解的属性(可选,格式:类型 名称() [default 默认值];)
    String value() default "执行方法"; // 日志描述,默认值“执行方法”
}

// 2. 业务类:使用自定义@Log注解
class UserService {
    // 标记方法需打印日志,指定日志描述
    @Log("用户登录")
    public void login(String username) {
        System.out.println("用户[" + username + "]登录成功");
    }

    // 标记方法需打印日志,使用默认日志描述
    @Log
    public void logout(String username) {
        System.out.println("用户[" + username + "]退出登录");
    }
}

// 3. 注解解析器:通过反射解析@Log注解,实现日志打印
import java.lang.reflect.Method;

public class AnnotationParser {
    public static void main(String[] args) throws Exception {
        // 创建业务类对象
        UserService userService = new UserService();
        
        // 反射获取UserService的Class对象
        Class<?> serviceClass = UserService.class;
        
        // 调用登录方法(带日志)
        Method loginMethod = serviceClass.getMethod("login", String.class);
        invokeWithLog(loginMethod, userService, "zhangsan");
        
        // 调用退出方法(带日志)
        Method logoutMethod = serviceClass.getMethod("logout", String.class);
        invokeWithLog(logoutMethod, userService, "zhangsan");
    }

    // 带日志的方法调用:解析@Log注解并打印日志
    private static void invokeWithLog(Method method, Object obj, Object... args) throws Exception {
        // 判断方法是否有@Log注解
        if (method.isAnnotationPresent(Log.class)) {
            // 获取@Log注解对象
            Log logAnnotation = method.getAnnotation(Log.class);
            // 获取注解的属性值(日志描述)
            String logDesc = logAnnotation.value();
            
            // 打印日志(模拟日志框架的功能)
            System.out.println("[日志] " + logDesc + ":开始执行");
            
            // 调用目标方法(反射执行)
            method.invoke(obj, args);
            
            // 打印方法执行完成日志
            System.out.println("[日志] " + logDesc + ":执行完成\n");
        } else {
            // 无@Log注解,直接调用方法
            method.invoke(obj, args);
        }
    }
}

输出结果

[日志] 用户登录:开始执行
用户[zhangsan]登录成功
[日志] 用户登录:执行完成

[日志] 执行方法:开始执行
用户[zhangsan]退出登录
[日志] 执行方法:执行完成

说明:自定义注解的核心是 “注解定义 + 解析器”,解析器通过反射(Class、Method类)获取注解信息,进而实现业务逻辑(如日志打印、参数校验),这也是 Spring、MyBatis 等框架的核心原理之一。

二十、Java 基础语法扩展建议

掌握上述基础语法后,可从以下方向进一步扩展学习,逐步向 “Java 开发工程师” 进阶:

  1. 集合框架深入:学习LinkedList、HashMap、HashSet等集合的底层实现(如数组 + 链表、红黑树),理解不同集合的适用场景;

  2. IO 流进阶:学习缓冲流(BufferedInputStream)、转换流(InputStreamReader)、对象流(ObjectOutputStream),掌握文件复制、对象序列化等实用功能;

  3. 多线程编程:学习Thread类、Runnable接口、线程池、锁机制(synchronized、Lock),理解并发编程的核心思想;

  4. 反射与注解:深入学习反射 API(Class、Constructor、Field),结合自定义注解实现框架级功能(如 ORM 映射、接口文档自动生成);

  5. 数据库操作:学习 JDBC 基础(连接数据库、CRUD 操作),进而学习 MyBatis、Spring Data JPA 等持久层框架;

  6. Web 开发入门:学习 Servlet、JSP 基础,了解 HTTP 协议,进而学习 Spring Boot 框架,快速开发 Web 应用。

Java 基础是后续进阶的基石,建议通过 “理论学习 + 代码实践” 结合的方式,多写案例(如学生管理系统、图书管理系统),逐步积累开发经验,提升解决实际问题的能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值