当前位置: 首页 > news >正文

JavaSE核心知识点03高级特性

🤟致敬读者

  • 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉

📘博主相关

  • 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息

文章目录

  • JavaSE核心知识点03高级特性
    • JavaSE核心知识点03高级特性03-01(集合框架)
    • 一、什么是集合框架(Collection Framework)?
      • 为什么需要集合框架?
    • 二、集合框架的核心结构
      • 1. **Collection 接口(单列集合)**
      • 2. **Map 接口(双列集合)**
    • 三、核心接口详解与代码示例
      • 1. **List 接口**
        • 特点:有序、可重复、可通过索引访问
      • 2. **Set 接口**
        • 特点:无序、不可重复(通过`equals()`和`hashCode()`判断)
      • 3. **Map 接口**
        • 特点:键值对存储,Key唯一
    • 四、集合框架的通用操作
      • 1. **遍历集合**
      • 2. **集合工具类 `Collections`**
    • 五、如何选择集合类?
    • 六、常见面试问题
    • 七、学习路线建议
    • JavaSE核心知识点03高级特性03-02(多线程)
      • **一、多线程基础概念**
      • **二、Java中创建线程的两种方式**
        • **1. 继承Thread类**
        • **2. 实现Runnable接口(推荐)**
      • **三、线程的生命周期**
      • **四、线程安全与同步**
        • **1. 问题:多个线程共享数据导致竞态条件**
        • **2. 解决方案:synchronized关键字**
        • **3. 使用Lock接口(更灵活)**
        • **4. volatile关键字**
      • **五、线程间通信**
      • **六、线程池(重点掌握)**
        • **1. 为什么使用线程池?**
        • **2. 使用Executors创建线程池**
        • **3. 自定义线程池(推荐)**
      • **七、常见问题与注意事项**
      • **八、实战练习**
    • JavaSE核心知识点03高级特性03-03(IO流)
      • **一、IO 流的作用**
      • **二、IO 流的分类**
        • 1. **按数据流向分**
        • 2. **按数据类型分**
      • **三、常用 IO 类**
        • 1. **字节流**
        • 2. **字符流**
        • 3. **其他工具类**
      • **四、代码示例**
        • 1. **字节流示例:复制图片**
        • 2. **字符流示例:读取文本文件**
        • 3. **控制台输入**
      • **五、关键注意事项**
      • **六、IO 流的选择**
      • **七、总结**
    • JavaSE核心知识点03高级特性03-04(Lambda表达式)
      • 一、Lambda表达式简介
      • 二、Lambda表达式基础语法
        • 示例对比:Lambda vs 匿名内部类
      • 三、函数式接口(Functional Interface)
        • 自定义函数式接口:
      • 四、Lambda表达式使用场景
        • 1. 替代匿名内部类
        • 2. 集合操作与Stream API
        • 3. 作为方法参数
      • 五、Lambda表达式进阶特性
        • 1. 方法引用(Method Reference)
        • 2. 变量作用域
        • 3. 类型推断
      • 六、注意事项
      • 七、综合示例
    • JavaSE核心知识点03高级特性03-05(注解)
      • 一、注解是什么?
        • 类比理解:
      • 二、Java 内置的常用注解
        • 1. `@Override`
        • 2. `@Deprecated`
        • 3. `@SuppressWarnings`
      • 三、如何自定义注解?
        • 1. 定义注解
        • 2. 元注解(Meta-Annotation)
      • 四、注解的处理方式
        • 1. 反射处理(运行时)
        • 2. 编译时处理(如 Lombok)
      • 五、实际应用场景
      • 六、注意事项
      • 七、总结


📃文章前言

  • 🔷文章均为学习工作中整理的笔记。
  • 🔶如有错误请指正,共同学习进步。


在这里插入图片描述

JavaSE核心知识点03高级特性

JavaSE核心知识点03高级特性03-01(集合框架)

好的!作为Java集合框架的入门学习指南,我将从基础概念、核心接口、常用实现类、使用场景到代码示例,逐步为你讲解。内容会尽量通俗易懂,配有代码示例和对比表格,帮助你快速掌握。


一、什么是集合框架(Collection Framework)?

集合框架 是Java中用于存储和操作一组对象的统一架构。它提供了一套标准化的接口和实现类,解决了数组的局限性(如固定长度、类型单一、操作复杂等)。

为什么需要集合框架?

  • 动态扩容:无需手动管理容量
  • 类型安全:通过泛型确保数据类型一致
  • 高性能操作:提供丰富的API(增删改查、排序、遍历等)
  • 统一标准:所有集合类遵循相同的接口规范

二、集合框架的核心结构

Java集合框架主要分为两大类:单列集合(Collection)双列集合(Map)

1. Collection 接口(单列集合)

  • List:有序、可重复
    • 常用实现类:ArrayList, LinkedList, Vector
  • Set:无序、不可重复
    • 常用实现类:HashSet, LinkedHashSet, TreeSet
  • Queue:队列,先进先出(FIFO)
    • 常用实现类:LinkedList, PriorityQueue

2. Map 接口(双列集合)

  • 键值对(Key-Value)存储,Key不可重复
  • 常用实现类:HashMap, LinkedHashMap, TreeMap, Hashtable

三、核心接口详解与代码示例

1. List 接口

特点:有序、可重复、可通过索引访问

常用实现类对比

实现类数据结构特点
ArrayList动态数组查询快,增删慢(需扩容或移动元素)
LinkedList双向链表增删快,查询慢(需遍历节点)
Vector同步的动态数组线程安全,性能较低(已逐渐被淘汰)

示例代码

// ArrayList示例
List<String> arrayList = new ArrayList<>();
arrayList.add("Apple");
arrayList.add("Banana");
arrayList.add(1, "Orange"); // 在索引1插入元素
System.out.println(arrayList); // [Apple, Orange, Banana]// LinkedList示例
List<Integer> linkedList = new LinkedList<>();
linkedList.add(10);
linkedList.addFirst(5); // 头部插入
linkedList.addLast(20); // 尾部插入
System.out.println(linkedList.get(1)); // 10

2. Set 接口

特点:无序、不可重复(通过equals()hashCode()判断)

常用实现类对比

实现类数据结构特点
HashSet哈希表最快查询,无顺序
LinkedHashSet哈希表+链表保留插入顺序
TreeSet红黑树自然排序或自定义排序

示例代码

// HashSet示例
Set<String> hashSet = new HashSet<>();
hashSet.add("Java");
hashSet.add("Python");
hashSet.add("Java"); // 重复元素不会被添加
System.out.println(hashSet); // 输出顺序不确定,如 [Java, Python]// TreeSet示例(自然排序)
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(5);
treeSet.add(2);
treeSet.add(8);
System.out.println(treeSet); // [2, 5, 8]

3. Map 接口

特点:键值对存储,Key唯一

常用实现类对比

实现类数据结构特点
HashMap哈希表最快查询,无顺序(允许null键值)
LinkedHashMap哈希表+链表保留插入顺序或访问顺序
TreeMap红黑树按键自然排序或自定义排序
Hashtable哈希表线程安全,不允许null键值(已过时)

示例代码

// HashMap示例
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Alice", 25);
hashMap.put("Bob", 30);
hashMap.put("Alice", 26); // 覆盖原有值
System.out.println(hashMap.get("Bob")); // 30// TreeMap示例(按键排序)
Map<String, Integer> treeMap = new TreeMap<>();
treeMap.put("Orange", 5);
treeMap.put("Apple", 3);
System.out.println(treeMap); // {Apple=3, Orange=5}

四、集合框架的通用操作

1. 遍历集合

  • for-each循环(推荐):

    List<String> list = Arrays.asList("A", "B", "C");
    for (String s : list) {System.out.println(s);
    }
    
  • 迭代器(Iterator)

    Iterator<String> it = list.iterator();
    while(it.hasNext()) {String s = it.next();if (s.equals("B")) it.remove(); // 安全删除元素
    }
    

2. 集合工具类 Collections

提供静态方法操作集合:

List<Integer> numbers = new ArrayList<>(Arrays.asList(3,1,4,2));
Collections.sort(numbers); // 排序 → [1,2,3,4]
Collections.reverse(numbers); // 反转 → [4,3,2,1]
Collections.shuffle(numbers); // 随机打乱

五、如何选择集合类?

根据需求选择最合适的集合:

场景推荐实现类
快速随机访问ArrayList
频繁插入删除LinkedList
去重且无需排序HashSet
去重且保留插入顺序LinkedHashSet
需要排序TreeSetTreeMap
键值对存储HashMap(最常用)
线程安全场景ConcurrentHashMap

六、常见面试问题

  1. ArrayList和LinkedList的区别?

    • ArrayList基于动态数组,适合随机访问;LinkedList基于链表,适合频繁增删。
  2. HashMap的工作原理?

    • 通过哈希函数计算键的哈希值,存储到对应桶(数组位置),解决哈希冲突使用链表或红黑树(JDK8+)。
  3. 如何保证集合的线程安全?

    • 使用Collections.synchronizedList()包装,或选择ConcurrentHashMapCopyOnWriteArrayList等并发集合。

七、学习路线建议

  1. 基础阶段:掌握ArrayListHashMapHashSet的常用操作
  2. 进阶阶段:理解底层数据结构(如哈希表、红黑树)、泛型、迭代器
  3. 高级阶段:学习线程安全集合、性能优化、Stream API操作集合

练习建议

  • 实现一个简单的学生管理系统(用集合存储学生信息)
  • 统计一篇文章中每个单词出现的次数(用HashMap
  • 比较不同集合在10万次操作下的性能差异

如果有具体问题或需要更多代码示例,欢迎随时提问!


JavaSE核心知识点03高级特性03-02(多线程)

学习Java多线程是一个循序渐进的过程,下面我会从基础到应用为你详细讲解,并附上代码示例帮助你理解。


一、多线程基础概念

1. 什么是线程?

  • 线程是程序执行的最小单位,一个进程可以包含多个线程,多个线程共享进程的内存资源。
  • 多线程允许程序同时执行多个任务,提高资源利用率和响应速度。

类比:想象一家餐厅,一个厨师(单线程)同时处理多个订单会手忙脚乱,多个厨师(多线程)分工协作效率更高。


二、Java中创建线程的两种方式

1. 继承Thread类
public class MyThread extends Thread {@Overridepublic void run() {System.out.println("线程执行: " + Thread.currentThread().getName());}public static void main(String[] args) {MyThread t1 = new MyThread();t1.start(); // 启动线程,JVM自动调用run()}
}

缺点:Java是单继承,继承Thread后无法继承其他类。

2. 实现Runnable接口(推荐)
public class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("线程执行: " + Thread.currentThread().getName());}public static void main(String[] args) {Thread t2 = new Thread(new MyRunnable());t2.start();}
}

优点:避免单继承限制,适合资源共享(如多个线程操作同一Runnable实例)。


三、线程的生命周期

线程的状态包括:

  1. 新建(New):创建未启动。
  2. 就绪(Runnable):调用start()后,等待CPU调度。
  3. 运行(Running):执行run()方法。
  4. 阻塞(Blocked):等待锁、I/O等资源。
  5. 终止(Terminated)run()执行完毕或异常退出。

四、线程安全与同步

1. 问题:多个线程共享数据导致竞态条件
public class Counter {private int count = 0;public void increment() {count++; // 非原子操作,可能被多个线程同时修改}
}
2. 解决方案:synchronized关键字
  • 同步方法:锁住当前对象实例。
public synchronized void increment() {count++;
}
  • 同步代码块:更细粒度控制。
public void increment() {synchronized(this) {count++;}
}
3. 使用Lock接口(更灵活)
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Counter {private int count = 0;private Lock lock = new ReentrantLock();public void increment() {lock.lock();try {count++;} finally {lock.unlock(); // 确保释放锁}}
}
4. volatile关键字
  • 保证变量可见性,但不保证原子性。
private volatile boolean flag = false;

五、线程间通信

使用wait()notify()notifyAll()实现线程协作(必须在同步块内调用)。

public class ProducerConsumer {private Queue<Integer> queue = new LinkedList<>();private int capacity = 5;public synchronized void produce(int item) throws InterruptedException {while (queue.size() == capacity) {wait(); // 队列满,等待}queue.add(item);notifyAll(); // 唤醒消费者}public synchronized int consume() throws InterruptedException {while (queue.isEmpty()) {wait(); // 队列空,等待}int item = queue.poll();notifyAll(); // 唤醒生产者return item;}
}

六、线程池(重点掌握)

1. 为什么使用线程池?
  • 避免频繁创建/销毁线程的开销。
  • 控制并发数量,防止资源耗尽。
2. 使用Executors创建线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolDemo {public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(3);for (int i = 0; i < 10; i++) {pool.execute(() -> {System.out.println(Thread.currentThread().getName() + " 执行任务");});}pool.shutdown(); // 关闭线程池}
}
3. 自定义线程池(推荐)
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.LinkedBlockingQueue;ThreadPoolExecutor executor = new ThreadPoolExecutor(5, // 核心线程数10, // 最大线程数60L, TimeUnit.SECONDS, // 空闲线程存活时间new LinkedBlockingQueue<>(100) // 任务队列
);

七、常见问题与注意事项

  1. 死锁:多个线程互相等待对方释放锁。

    • 避免方法:按固定顺序获取锁,使用超时机制(tryLock)。
  2. 线程泄漏:线程未正确关闭导致资源耗尽。

    • 解决:使用try-finally确保资源释放。
  3. 避免使用已废弃方法

    • stop():强制终止线程,可能导致数据不一致。
    • 改用标志位控制线程退出:
    public class SafeStop implements Runnable {private volatile boolean running = true;public void stop() {running = false;}@Overridepublic void run() {while (running) {// 执行任务}}
    }
    

八、实战练习

题目:模拟10个窗口卖100张票(线程安全)。

public class TicketSales implements Runnable {private int tickets = 100;private final Object lock = new Object();@Overridepublic void run() {while (true) {synchronized (lock) {if (tickets <= 0) break;System.out.println(Thread.currentThread().getName() + " 卖出第 " + tickets-- + " 张票");}try {Thread.sleep(100); // 模拟操作耗时} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {TicketSales task = new TicketSales();for (int i = 0; i < 10; i++) {new Thread(task, "窗口" + (i+1)).start();}}
}

通过以上内容,你应该对Java多线程有了全面的认识。学习时建议多写代码调试,观察不同情况下的输出,逐步理解线程的行为。遇到问题可以查阅Java官方文档或可靠的教程资源。


JavaSE核心知识点03高级特性03-03(IO流)

好的!Java 中的 IO 流是处理输入/输出操作的核心工具,我会尽量用通俗易懂的方式为你讲解,分为以下几个部分:


一、IO 流的作用

IO(Input/Output)流用于处理数据的输入和输出,例如:

  • 从文件读取数据(输入)
  • 向文件写入数据(输出)
  • 网络数据传输
  • 控制台输入输出

二、IO 流的分类

Java IO 流主要分为两大类:

1. 按数据流向分
  • 输入流(Input Stream):从外部(如文件)读取数据到程序。
  • 输出流(Output Stream):将程序中的数据写入到外部(如文件)。
2. 按数据类型分
  • 字节流(Byte Stream):以字节(8-bit)为单位处理数据,适用于所有文件类型(如图片、视频、文本等)。
    • 核心类:InputStreamOutputStream
  • 字符流(Character Stream):以字符(16-bit Unicode)为单位处理数据,专为文本文件设计(如 .txt.java)。
    • 核心类:ReaderWriter

三、常用 IO 类

1. 字节流
  • 文件读写
    • FileInputStream:读取字节文件
    • FileOutputStream:写入字节文件
  • 缓冲流(高效读写)
    • BufferedInputStream:带缓冲的字节输入流
    • BufferedOutputStream:带缓冲的字节输出流
2. 字符流
  • 文件读写
    • FileReader:读取字符文件
    • FileWriter:写入字符文件
  • 缓冲流(高效读写)
    • BufferedReader:带缓冲的字符输入流
    • BufferedWriter:带缓冲的字符输出流
3. 其他工具类
  • Scanner:方便读取控制台输入或解析文件。
  • PrintWriter:格式化输出文本。

四、代码示例

1. 字节流示例:复制图片
try (FileInputStream fis = new FileInputStream("input.jpg");FileOutputStream fos = new FileOutputStream("output.jpg")
) {byte[] buffer = new byte[1024];int length;while ((length = fis.read(buffer)) != -1) {fos.write(buffer, 0, length);}
} catch (IOException e) {e.printStackTrace();
}
2. 字符流示例:读取文本文件
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))
) {String line;while ((line = br.readLine()) != null) {System.out.println(line);}
} catch (IOException e) {e.printStackTrace();
}
3. 控制台输入
Scanner scanner = new Scanner(System.in);
System.out.print("请输入内容:");
String input = scanner.nextLine();
System.out.println("你输入的是:" + input);
scanner.close();

五、关键注意事项

  1. 资源关闭
    • 必须用 close() 关闭流,或使用 try-with-resources(Java 7+)自动关闭。
  2. 缓冲流提升性能
    • 使用 BufferedInputStreamBufferedReader 等缓冲类减少IO次数。
  3. 字符编码问题
    • 读写文本文件时,需注意编码(如 UTF-8),可使用 InputStreamReader 指定编码:
      new InputStreamReader(new FileInputStream("file.txt"), StandardCharsets.UTF_8);
      

六、IO 流的选择

  • 字节流:处理非文本文件(如图片、音频)或未知文件类型。
  • 字符流:处理文本文件,避免乱码问题。

七、总结

Java IO 流的核心是理解字节流与字符流的区别,掌握常用类的用法,并注意资源管理和编码问题。建议通过实际项目(如文件复制、日志记录)加深理解。

如果有具体问题或需要更多示例,可以随时问我! 😊


JavaSE核心知识点03高级特性03-04(Lambda表达式)

好的,让我们一步步深入了解Java中的Lambda表达式。

一、Lambda表达式简介

Lambda表达式是Java 8引入的一种简洁的匿名函数写法,主要用于简化函数式接口(仅含一个抽象方法的接口)的实现。它使得代码更简洁、易读,尤其在处理集合和并发任务时效果显著。


二、Lambda表达式基础语法

Lambda的基本结构如下:

(参数列表) -> { 方法体 }
  • 参数列表:与接口方法参数一致,类型可省略。
  • 箭头符号->:分隔参数和方法体。
  • 方法体:单行代码可省略{}return,多行则必须使用。
示例对比:Lambda vs 匿名内部类

匿名内部类

Runnable r = new Runnable() {@Overridepublic void run() {System.out.println("Hello World");}
};

Lambda表达式

Runnable r = () -> System.out.println("Hello World");

三、函数式接口(Functional Interface)

函数式接口是Lambda表达式的核心,Java内置了多种常用接口:

接口方法用途
Runnablevoid run()无参无返回值
Consumer<T>void accept(T)消费一个参数
Supplier<T>T get()提供返回值
Function<T,R>R apply(T)接收T类型,返回R类型
Predicate<T>boolean test(T)条件判断
自定义函数式接口:
@FunctionalInterface
interface Greeting {void sayHello(String name);
}// 使用Lambda
Greeting greet = name -> System.out.println("Hello, " + name);
greet.sayHello("Alice"); // 输出:Hello, Alice

四、Lambda表达式使用场景

1. 替代匿名内部类

简化事件监听、线程创建等代码:

// 传统方式
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Running!");}
}).start();// Lambda方式
new Thread(() -> System.out.println("Running!")).start();
2. 集合操作与Stream API

结合Stream处理集合,代码更简洁:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");// 过滤并打印长度>3的名字
names.stream().filter(name -> name.length() > 3).forEach(System.out::println);
// 输出:Alice, Charlie
3. 作为方法参数

传递行为而非值:

public static void processList(List<Integer> list, Consumer<Integer> processor) {for (Integer num : list) {processor.accept(num);}
}// 调用
processList(Arrays.asList(1, 2, 3), num -> System.out.println(num * 2));
// 输出:2, 4, 6

五、Lambda表达式进阶特性

1. 方法引用(Method Reference)

进一步简化Lambda,四种形式:

  • 静态方法类名::方法名
  • 实例方法对象::方法名
  • 任意对象的实例方法类名::方法名
  • 构造方法类名::new

示例:

// Lambda写法
Consumer<String> c1 = s -> System.out.println(s);
// 方法引用
Consumer<String> c2 = System.out::println;List<String> names = Arrays.asList("Alice", "Bob");
names.forEach(System.out::println); // 输出每个元素
2. 变量作用域

Lambda可以访问final或等效final的局部变量:

int limit = 5; // 等效final
List<Integer> numbers = Arrays.asList(1, 2, 3, 6);
numbers.stream().filter(n -> n < limit) // 正确:limit不可修改.forEach(System.out::println);
3. 类型推断

编译器根据上下文推断参数类型:

// 完整写法
Function<String, Integer> f1 = (String s) -> s.length();
// 简化写法(省略类型)
Function<String, Integer> f2 = s -> s.length();

六、注意事项

  1. 仅用于函数式接口:Lambda只能替代单一抽象方法的接口。
  2. 省略规则
    • 单参数可省略()s -> s.length()
    • 单行代码可省略{}return(a, b) -> a + b
  3. this关键字:Lambda中的this指向外部类,而非Lambda自身。

七、综合示例

场景:使用Lambda和Stream对用户列表进行排序和过滤。

List<User> users = Arrays.asList(new User("Alice", 25),new User("Bob", 30),new User("Charlie", 20)
);// 按年龄排序,过滤年龄≥25,提取用户名
List<String> names = users.stream().sorted((u1, u2) -> u1.getAge() - u2.getAge()).filter(u -> u.getAge() >= 25).map(User::getName).collect(Collectors.toList());System.out.println(names); // 输出:[Alice, Bob]

通过以上内容,你应该能够掌握Lambda的基本用法和常见场景。建议多实践,尝试将现有的匿名类重构为Lambda,并熟悉Stream API的使用,以充分发挥Lambda的优势。


JavaSE核心知识点03高级特性03-05(注解)

好的!我来为你详细讲解 Java 中的注解(Annotation),内容会循序渐进,尽量通俗易懂。以下是完整的学习路径:


一、注解是什么?

注解(Annotation)是 Java 中的一种元数据(描述数据的数据),它本身不直接影响代码逻辑,但可以为代码提供额外的信息。类似于“标签”,用来标记代码的特殊行为或配置。

类比理解:
  • 想象你在一本书上贴便利贴,便利贴本身不改变书的内容,但能提醒你注意某些部分(如“重点”、“待办”)。注解的作用类似。

二、Java 内置的常用注解

Java 提供了一些内置注解,以下是几个常见的:

1. @Override
  • 作用:标记方法是为了覆盖父类或接口中的方法。
  • 示例
    @Override
    public String toString() {return "This is a custom toString()";
    }
    
  • 用途:帮助编译器检查是否正确覆盖了父类方法(避免拼写错误)。
2. @Deprecated
  • 作用:标记方法、类或字段已过时,不推荐使用。
  • 示例
    @Deprecated
    public void oldMethod() {// 过时的方法
    }
    
  • 效果:调用该方法时,编译器会生成警告。
3. @SuppressWarnings
  • 作用:抑制编译器警告。
  • 示例
    @SuppressWarnings("unchecked")
    public void someMethod() {List list = new ArrayList(); // 这里会有“未检查类型”的警告,但被注解抑制
    }
    

三、如何自定义注解?

你可以创建自己的注解,以下是步骤:

1. 定义注解

使用 @interface 关键字:

// 定义一个名为 MyAnnotation 的注解
public @interface MyAnnotation {String value() default ""; // 注解的参数int priority() default 0;
}
2. 元注解(Meta-Annotation)

元注解是用于修饰注解的注解,用来定义注解的行为:

元注解作用
@Target指定注解可以应用的位置(如类、方法、字段等)。
@Retention指定注解的保留策略(源码级、编译期、运行时)。
@Documented注解会被包含在 Javadoc 中。
@Inherited子类可以继承父类的注解。

示例:定义一个用于方法的运行时注解

import java.lang.annotation.*;@Target(ElementType.METHOD) // 只能用在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface MyMethodAnnotation {String description() default "默认描述";boolean enabled() default true;
}

四、注解的处理方式

注解本身没有行为,需要通过反射或编译时处理来触发逻辑。

1. 反射处理(运行时)

通过反射读取注解信息:

public class Test {@MyMethodAnnotation(description = "这是一个测试方法")public void testMethod() {// 方法内容}public static void main(String[] args) throws NoSuchMethodException {Method method = Test.class.getMethod("testMethod");if (method.isAnnotationPresent(MyMethodAnnotation.class)) {MyMethodAnnotation annotation = method.getAnnotation(MyMethodAnnotation.class);System.out.println("描述:" + annotation.description()); // 输出:这是一个测试方法System.out.println("是否启用:" + annotation.enabled()); // 输出:true}}
}
2. 编译时处理(如 Lombok)

通过注解处理器(Annotation Processing Tool, APT)在编译时生成代码。例如 Lombok 的 @Data 注解会自动生成 getter/setter。


五、实际应用场景

  1. 框架配置(如 Spring):

    @Service
    public class UserService {@Autowiredprivate UserRepository userRepository;
    }
    
  2. 单元测试(如 JUnit):

    @Test
    public void testAddition() {assertEquals(4, 2 + 2);
    }
    
  3. 序列化/反序列化(如 Jackson):

    public class User {@JsonProperty("user_name")private String userName;
    }
    

六、注意事项

  1. 保留策略:如果需要在运行时获取注解,必须设置 @Retention(RetentionPolicy.RUNTIME)
  2. 目标范围:用 @Target 明确注解的应用位置(如 ElementType.TYPE 表示类)。
  3. 默认值:注解参数需定义默认值(如 default ""),否则使用时必须显式赋值。
  4. 参数类型限制:注解的参数只能是基本类型、String、Class、枚举或数组。

七、总结

  • 注解的作用:提供元数据,辅助代码分析或配置。
  • 核心步骤:定义注解 → 用元注解修饰 → 处理注解逻辑(反射/APT)。
  • 学习建议:从简单注解开始,尝试结合反射实现功能(如自定义日志注解)。

动手练习:

  1. 定义一个注解 @LogExecutionTime,用于记录方法的执行时间。
  2. 通过反射在方法执行前后计算时间差。

如果有疑问,可以随时提出!




📜文末寄语

  • 🟠关注我,获取更多内容。
  • 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
  • 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
  • 🔵​加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
  • 🟣点击下方名片获取更多内容🍭🍭🍭👇

相关文章:

  • JavaScript数据类型及内置函数详解目录
  • 【MYSQL】索引、存储引擎
  • Next.js V15 在异步页面中,获取路由动态参数的几个坑
  • 【二刷力扣】【力扣热题100】今天的题目是:283.移动零
  • 2025.5.22 Axure 基础与线框图制作学习笔记
  • 大数据Spark(六十):Spark On Yarn 配置
  • 软件工程重点复习
  • C++学习之打车软件—高德地图API
  • 图解 | 大模型智能体LLM Agents
  • 网络原理入门详解:从零理解互联网如何工作
  • mysql知识点1--了解数据库
  • c/c++的opencv椒盐噪声
  • 学习日志12 java
  • 【IPMV】图像处理与机器视觉:Lec12 Blob Detector 斑点检测
  • MLA:Transformer的智能变形金刚——解密多头潜在注意力的进化密码
  • DOM事件的传播机制
  • Dify 本地源码安装教程
  • Llama 4中文调优全流程解
  • Win11 系统登入时绑定微软邮箱导致用户名欠缺
  • ST表——算法的优化
  • 网站建设中html下载/中国新闻
  • 推广qq群的网站/google play store
  • 太原网站建设优化/云搜索下载
  • 企业宣传网站建设需求说明书的模板/整合营销传播成功案例
  • 网站seo诊断优化分析该怎么做/百度热搜榜第一
  • 成都网站建设优惠活动/长春视频剪辑培训机构