Java 基础及版本特性全面指南
目录
1. Java 语言基础
1.1 原始数据类型
| 类型 | 大小 | 最小值 | 最大值 |
|---|---|---|---|
| byte | 8 bit | -128 | 127 |
| short | 16 bit | -32768 | 32767 |
| int | 32 bit | -2^31 | 2^31-1 |
| long | 64 bit | -2^63 | 2^63-1 |
| float | 32 bit | Float.MIN_VALUE | Float.MAX_VALUE |
| double | 64 bit | Double.MIN_VALUE | Double.MAX_VALUE |
| char | 16 bit | \u0000 | \uffff |
| boolean | - | false | true |
java
// 获取数据类型大小和范围
System.out.println("Byte: " + Byte.SIZE + " bits, Min: " + Byte.MIN_VALUE + ", Max: " + Byte.MAX_VALUE);
System.out.println("Integer: " + Integer.SIZE + " bits, Min: " + Integer.MIN_VALUE + ", Max: " + Integer.MAX_VALUE);1.2 类型转换
自动类型提升(Widening):
java
byte + short → int
int + float → float
long + double → double显式类型转换(Narrowing):
java
int i = (int) 3.14; // 结果为 3
long l = 100L;
int j = (int) l; // 可能丢失精度1.3 面向对象四大原则
- 封装(Encapsulation): 隐藏内部实现细节
- 继承(Inheritance): 复用父类代码
- 多态(Polymorphism): 同一接口不同实现
- 抽象(Abstraction): 提取共同特征
1.4 访问修饰符
| 修饰符 | 同类 | 同包 | 子类 | 全局 |
|---|---|---|---|---|
| private | ✓ | ✗ | ✗ | ✗ |
| default | ✓ | ✓ | ✗ | ✗ |
| protected | ✓ | ✓ | ✓ | ✗ |
| public | ✓ | ✓ | ✓ | ✓ |
1.5 关键字详解
final 关键字:
java
// final 变量 - 常量
final int MAX = 100;
// final 方法 - 不能重写
public final void hello() { }
// final 类 - 不能继承
final class Math { }static 关键字:
java
class Counter {
static int count = 0; // 类变量
static { // 静态代码块
count = 10;
}
static void print() { // 静态方法
System.out.println(count);
}
}this vs super:
java
class Child extends Parent {
this.field; // 当前对象字段
super.method(); // 调用父类方法
}其他非访问修饰符:
abstract: 抽象类/方法synchronized: 同步控制volatile: 保证可见性transient: 序列化跳过native: 本地方法
1.6 String 类
不可变性:
java
String s = "Sachin";
s.concat(" Tendulkar"); // 原字符串不变
System.out.println(s); // 输出 "Sachin"String Pool:
java
String s1 = "HELLO";
String s2 = "HELLO";
String s3 = new String("HELLO");
System.out.println(s1 == s2); // true (池内相同引用)
System.out.println(s1 == s3); // false (堆上新对象)
System.out.println(s1.equals(s3)); // true (内容相等)StringBuilder vs StringBuffer:
java
// StringBuilder - 非线程安全,高性能
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" World");
// StringBuffer - 线程安全
StringBuffer sf = new StringBuffer();
sf.append("Hello").append(" World");2. JVM 架构与内存管理
2.1 JVM 内存区域
┌─────────────────────────────────────┐
│ Method Area │ ← 类信息、静态变量、常量池
│ (Metaspace in JDK8+) │
├─────────────────────────────────────┤
│ Heap │ ← 对象实例、数组
│ ┌──────────────┬────────────────┐ │
│ │ Young Gen │ Old Generation │ │
│ │ (Eden+S0+S1) │ │ │
│ └──────────────┴────────────────┘ │
├─────────────────────────────────────┤
│ Stack (per thread) │ ← 局部变量、方法调用
│ ┌─────────┐ ┌─────────┐ │
│ │ Frame 1 │ │ Frame 2 │ ... │
│ └─────────┘ └─────────┘ │
├─────────────────────────────────────┤
│ PC Register (per thread) │ ← 指令地址
├─────────────────────────────────────┤
│ Native Method Stack │ ← 本地方法
└─────────────────────────────────────┘代码示例:
java
public class MemoryDemo {
static int staticVar = 100; // Method Area
public static void main(String[] args) {
int localVar = 10; // Stack
Student student = new Student("Alice", 20); // Heap
display(student); // Stack Frame
System.gc(); // Native Method Stack
}
static void display(Student s) {
System.out.println(s.name);
}
}2.2 ClassLoader 层次结构
Bootstrap ClassLoader (C++)
↑
Extension/Platform ClassLoader
↑
Application/System ClassLoader
↑
Custom ClassLoader委托模型:
java
protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
Class c = findLoadedClass(name);
if (c == null) {
if (parent != null) {
c = parent.loadClass(name, false); // 先委托父加载器
} else {
c = findBootstrapClass0(name);
}
}
return c;
}自定义 ClassLoader:
java
public class MyClassLoader extends ClassLoader {
private String classPath;
public MyClassLoader(String classPath) {
super();
this.classPath = classPath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] classData = loadClassData(name);
return defineClass(name, classData, 0, classData.length);
}
private byte[] loadClassData(String className) {
// 从指定路径加载.class 文件
}
}2.3 类加载过程
- Loading(加载): 读取字节码
- Linking(连接):
- Verification(验证)
- Preparation(准备)
- Resolution(解析)
- Initialization(初始化): 执行静态初始化器和静态块
java
class GFG {
static {
System.out.println("GFG class is loaded!"); // 初始化阶段执行
}
}
public class Test {
public static void main(String[] args) throws Exception {
Class.forName("GFG"); // 触发类加载
}
}2.4 JIT 编译
工作原理:
- 解释执行初始代码
- 热点检测后 JIT 编译为本地机器码
- 直接执行编译后的代码提高性能
编译策略:
- C1 Compiler: 快速编译,优化较少
- C2 Compiler: 深度优化,编译较慢
3. 垃圾回收机制
3.1 GC 算法分类
| GC 类型 | 特点 | 适用场景 | JVM 参数 |
|---|---|---|---|
| Serial GC | 单线程,Stop-The-World | 客户端应用 | -XX:+UseSerialGC |
| Parallel GC | 多线程,STW | 批处理任务 | -XX:+UseParallelGC |
| CMS | 并发标记清除,低停顿 | 延迟敏感应用 | -XX:+UseConcMarkSweepGC |
| G1GC | 分区回收,可预测停顿 | 大堆内存 | -XX:+UseG1GC |
| ZGC | 超低停顿 (<10ms) | 超大堆 (>16GB) | -XX:+UseZGC |
| Shenandoah | 并发压缩,低停顿 | 大堆低延迟 | -XX:+UseShenandoahGC |
3.2 对象存活判定
可达性分析:
java
// GC Roots 包括:
// 1. 虚拟机栈中引用的对象
// 2. 方法区中类静态属性引用的对象
// 3. 方法区中常量引用的对象
// 4. 本地方法栈中 JNI 引用对象引用类型:
java
// Strong Reference - 强引用
Object obj = new Object();
// Soft Reference - 软引用(内存不足时回收)
SoftReference<Object> softRef = new SoftReference<>(new Object());
// Weak Reference - 弱引用(GC 时一定回收)
WeakReference<Object> weakRef = new WeakReference<>(new Object());
// Phantom Reference - 虚引用(用于跟踪回收)
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, queue);3.3 对象创建与 GC 时机
java
class Test {
String name;
Test(String name) { this.name = name; }
@Override
protected void finalize() throws Throwable {
System.out.println(name + " garbage collected");
}
}
static void createObjects() {
Test t = new Test("temp"); // 方法结束后成为 GC 候选
}
public static void main(String[] args) {
createObjects();
System.gc(); // 建议 GC(不保证执行)
}3.4 GC 调优参数
bash
# 堆内存设置
-Xms2g -Xmx4g # 初始/最大堆大小
-XX:MetaspaceSize=256m # Metaspace 初始大小
-XX:MaxMetaspaceSize=512m # Metaspace 最大大小
-Xss1m # 线程栈大小
# GC 日志
-XX:+PrintGCDetails # 详细 GC 日志
-XX:+PrintGCDateStamps # 带时间戳
-Xloggc:/path/gc.log # GC 日志文件
# G1GC 调优
-XX:MaxGCPauseMillis=200 # 目标最大停顿时间
-XX:G1HeapRegionSize=16m # Region 大小
# OOM 处理
-XX:+HeapDumpOnOutOfMemoryError # OOM 时生成堆转储
-XX:HeapDumpPath=/path/dump.hprof4. 并发编程
4.1 线程创建方式
java
// 1. 继承 Thread 类
class MyThread extends Thread {
public void run() {
System.out.println("Thread running");
}
}
// 2. 实现 Runnable 接口
class RunnableTask implements Runnable {
public void run() {
System.out.println("Runnable task");
}
}
// 3. 使用 Lambda
Runnable task = () -> System.out.println("Lambda task");
// 4. 实现 Callable(有返回值)
Callable<String> callable = () -> "Result";4.2 线程池
java
// 固定线程池
ExecutorService fixedPool = Executors.newFixedThreadPool(4);
// 单线程池
ExecutorService singlePool = Executors.newSingleThreadExecutor();
// 缓存线程池
ExecutorService cachedPool = Executors.newCachedThreadPool();
// 调度线程池
ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(4);
// 自定义线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
4, // corePoolSize
8, // maximumPoolSize
60L, TimeUnit.SECONDS, // keepAliveTime
new LinkedBlockingQueue<>(),// workQueue
new ThreadPoolExecutor.CallerRunsPolicy() // handler
);4.3 同步机制
synchronized:
java
class Counter {
private int count = 0;
// 同步方法
public synchronized void increment() {
count++;
}
// 同步代码块
public void add() {
synchronized(this) {
count++;
}
}
// 静态同步(锁类对象)
public static synchronized void staticMethod() {
// ...
}
}volatile:
java
class VolatileExample {
private volatile boolean running = true;
void stop() { running = false; } // 对其他线程立即可见
}Lock 接口:
java
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// 临界区代码
} finally {
lock.unlock();
}
// 公平锁
ReentrantLock fairLock = new ReentrantLock(true);
// 尝试锁定
if (lock.tryLock(100, TimeUnit.MILLISECONDS)) {
try { /* ... */ } finally { lock.unlock(); }
}4.4 并发工具类
CountDownLatch:
java
CountDownLatch latch = new CountDownLatch(3);
// 多个线程完成任务
for (int i = 0; i < 3; i++) {
new Thread(() -> {
// 执行任务
latch.countDown();
}).start();
}
// 主线程等待
latch.await();
System.out.println("所有任务完成");CyclicBarrier:
java
CyclicBarrier barrier = new CyclicBarrier(3,
() -> System.out.println("所有线程到达屏障"));
// 三个线程在 barrier 处等待彼此
new Thread(() -> {
// ...
barrier.await();
}).start();Semaphore:
java
Semaphore semaphore = new Semaphore(3); // 最多 3 个许可
semaphore.acquire(); // 获取许可
try {
// 访问资源
} finally {
semaphore.release(); // 释放许可
}4.5 并发容器
java
// ConcurrentHashMap - 线程安全 Map
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
// CopyOnWriteArrayList - 读多写少场景
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
// BlockingQueue - 阻塞队列
BlockingQueue<String> queue = new ArrayBlockingQueue<>(100);
queue.put("item"); // 队满阻塞
String item = queue.take(); // 队空阻塞
// ConcurrentLinkedQueue - 无界非阻塞队列
ConcurrentLinkedQueue<String> linkedQueue = new ConcurrentLinkedQueue<>();4.6 CompletableFuture 异步编程
java
// 基本用法
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
return fetchData();
});
// thenApply - 数据转换
future.thenApply(result -> result.toUpperCase());
// thenAccept - 消费结果
future.thenAccept(result -> System.out.println(result));
// thenRun - 完成后的动作(无参数)
future.thenRun(() -> System.out.println("Done"));
// 组合多个异步任务
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
// 两个都完成后合并结果
CompletableFuture<Integer> sum = future1.thenCombine(future2, (a, b) -> a + b);
// 任意一个完成即返回
CompletableFuture<String> first = CompletableFuture.anyOf(f1, f2, f3);
// 全部完成后返回
CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3);
// 异常处理
future.exceptionally(ex -> "Default Value");
future.handle((result, ex) -> {
if (ex != null) return "Error: " + ex.getMessage();
return result;
});
// 嵌套依赖
future.thenCompose(result ->
CompletableFuture.supplyAsync(() -> process(result))
);4.7 虚拟线程(Java 21)
java
// 创建虚拟线程
Thread virtualThread = Thread.startVirtualThread(() -> {
System.out.println("Running on virtual thread");
});
// 虚拟线程池
try (ExecutorService executor =
ExecutorService.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10000; i++) {
executor.submit(() -> doTask());
}
}5. 集合框架
5.1 集合体系
Collection
├── List
│ ├── ArrayList - 数组实现,随机访问快
│ ├── LinkedList - 双向链表,插入删除快
│ └── Vector - 线程安全的 ArrayList
│
├── Set
│ ├── HashSet - HashMap 实现,无序
│ ├── TreeSet - TreeMap 实现,有序
│ └── LinkedHashSet - 保持插入顺序
│
└── Queue
├── PriorityQueue - 优先队列
├── ArrayDeque - 双端队列
└── LinkedList5.2 List 操作
java
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
// 访问
int value = list.get(0);
// 修改
list.set(0, 10);
// 删除
list.remove(Integer.valueOf(1)); // 注意:传对象而非基本类型
// 遍历
for (Integer i : list) { } // foreach
list.forEach(System.out::println); // Stream
Iterator<Integer> it = list.iterator(); // Iterator
while(it.hasNext()) { it.next(); }
// sublist
List<Integer> sub = list.subList(1, 3);5.3 Set 操作
java
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("A"); // 重复元素不会被添加
// 有序 Set
Set<String> sortedSet = new TreeSet<>();
sortedSet.add("C");
sortedSet.add("A");
sortedSet.add("B");
// 输出:A B C
// 保持插入顺序
Set<String> orderedSet = new LinkedHashSet<>();
orderedSet.add("First");
orderedSet.add("Second");
orderedSet.add("Third");
// 按插入顺序迭代5.4 Map 操作
java
Map<String, Integer> map = new HashMap<>();
map.put("one", 1);
map.put("two", 2);
// 获取
Integer value = map.get("one");
Integer defaultValue = map.getOrDefault("three", 0);
// 计算或更新
map.merge("one", 1, (oldVal, newVal) -> oldVal + newVal);
map.computeIfAbsent("two", k -> 100);
// 遍历
map.forEach((k, v) -> System.out.println(k + "=" + v));
map.keySet().forEach(key -> System.out.println(key));
map.values().forEach(value -> System.out.println(value));
map.entrySet().forEach(entry -> System.out.println(entry));
// 有序 Map
Map<String, Integer> sortedMap = new TreeMap<>(); // 按键排序
Map<String, Integer> LinkedHashMap = new LinkedHashMap<>(); // 按插入顺序5.5 Comparator 与 Comparable
java
// Comparable - 自然排序
class Person implements Comparable<Person> {
String name;
int age;
@Override
public int compareTo(Person other) {
return this.age - other.age; // 按年龄排序
}
}
// Comparator - 自定义排序
List<Person> people = ...;
// Lambda 表达式
people.sort(Comparator.comparingInt(p -> p.age));
people.sort(Comparator.comparing(Person::getName).thenComparingInt(p -> p.age));
// 降序
people.sort(Comparator.comparingInt(p -> p.age).reversed());5.6 Stream API
java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// filter - 过滤
names.stream()
.filter(n -> n.startsWith("A"))
.forEach(System.out::println);
// map - 转换
List<Integer> lengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
// sorted - 排序
names.stream()
.sorted()
.forEach(System.out::println);
// distinct - 去重
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3);
numbers.stream().distinct().forEach(System.out::println);
// limit/skip
names.stream()
.limit(2) // 前 2 个
.forEach(System.out::println);
names.stream()
.skip(2) // 跳过前 2 个
.forEach(System.out::println);
// collect - 收集
List<String> result = names.stream()
.filter(n -> n.length() > 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
// reduce - 归约
int sum = IntStream.of(1, 2, 3, 4, 5)
.reduce(0, (a, b) -> a + b);
// anyMatch/allMatch/noneMatch
boolean hasLongName = names.stream()
.anyMatch(n -> n.length() > 5);
boolean allPositive = numbers.stream()
.allMatch(n -> n > 0);
// 并行流
names.parallelStream()
.filter(...)
.forEach(...);6. 异常处理
6.1 异常体系
Throwable
├── Error - JVM 错误,通常无法恢复
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ └── ...
│
└── Exception - 程序可处理的异常
├── Checked Exception - 必须捕获或声明
│ ├── IOException
│ ├── SQLException
│ └── ClassNotFoundException
│
└── RuntimeException - 运行时异常,无需强制捕获
├── NullPointerException
├── ArrayIndexOutOfBoundsException
├── IllegalArgumentException
└── ...6.2 try-catch-finally
java
try {
// 可能抛出异常的代码
int result = 10 / 0;
} catch (ArithmeticException e) {
// 处理特定异常
System.err.println("除零错误");
} catch (Exception e) {
// 处理其他异常
e.printStackTrace();
} finally {
// 总是执行(无论是否异常)
cleanup();
}6.3 throw vs throws
java
// throw - 主动抛出异常
public void checkAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
}
// throws - 声明可能抛出的异常
public void readFile() throws IOException {
FileReader fr = new FileReader("file.txt");
}6.4 自定义异常
java
// 检查异常
public class BusinessException extends Exception {
private final String errorCode;
public BusinessException(String message, String errorCode) {
super(message);
this.errorCode = errorCode;
}
}
// 运行时异常
public class ValidationException extends RuntimeException {
public ValidationException(String message) {
super(message);
}
}
// 使用
try {
throw new BusinessException("业务失败", "E001");
} catch (BusinessException e) {
System.err.println("错误码:" + e.errorCode);
}6.5 try-with-resources
java
// 自动关闭实现了 AutoCloseable 的资源
try (FileReader fr = new FileReader("input.txt");
FileWriter fw = new FileWriter("output.txt")) {
int data;
while ((data = fr.read()) != -1) {
fw.write(data);
}
} catch (IOException e) {
e.printStackTrace();
}
// 不需要 finally 关闭资源7. IO 与 NIO
7.1 传统 IO
字节流:
java
// 输入流
try (FileInputStream fis = new FileInputStream("input.bin");
FileOutputStream fos = new FileOutputStream("output.bin")) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
// 缓冲流(提高性能)
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("input.bin"));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("output.bin"))) {
// ...
}字符流:
java
// BufferedReader - 高效读取文本
try (BufferedReader reader = new BufferedReader(
new FileReader("input.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
// BufferedWriter - 高效写入文本
try (BufferedWriter writer = new BufferedWriter(
new FileWriter("output.txt"))) {
writer.write("Hello World");
writer.newLine();
}7.2 NIO
Channel 和 Buffer:
java
Path inputPath = Paths.get("input.txt");
Path outputPath = Paths.get("output.txt");
try (FileChannel inputChannel = FileChannel.open(inputPath, StandardOpenOption.READ);
FileChannel outputChannel = FileChannel.open(outputPath,
StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (inputChannel.read(buffer) != -1) {
buffer.flip();
outputChannel.write(buffer);
buffer.clear();
}
}Files 工具类:
java
// 读取整个文件
List<String> lines = Files.readAllLines(Paths.get("file.txt"), StandardCharsets.UTF_8);
byte[] bytes = Files.readAllBytes(Paths.get("file.bin"));
// 写入文件
Files.write(Paths.get("output.txt"),
Collections.singletonList("Hello"),
StandardCharsets.UTF_8);
// 复制文件
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
// 移动/重命名文件
Files.move(sourcePath, targetPath, StandardCopyOption.ATOMIC_MOVE);
// 删除文件
Files.delete(path);
// 创建临时文件
Path temp = Files.createTempFile("prefix", ".suffix");
// 列出目录内容
try (DirectoryStream<Path> stream = Files.newDirectoryStream(
Paths.get("/path/to/dir"), "*.java")) {
for (Path file : stream) {
System.out.println(file.getFileName());
}
}
// 递归遍历目录
Files.walkFileTree(Paths.get("/path"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
});Files 属性:
java
Path path = Paths.get("file.txt");
// 基本属性
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Size: " + attrs.size());
System.out.println("Is Directory: " + attrs.isDirectory());
System.out.println("Last Modified: " + attrs.lastModifiedTime());
// 判断存在性
boolean exists = Files.exists(path);
boolean isReadable = Files.isReadable(path);
boolean isRegularFile = Files.isRegularFile(path);8. 泛型
8.1 泛型类和方法
java
// 泛型类
class Box<T> {
private T content;
public void set(T content) { this.content = content; }
public T get() { return content; }
}
Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String s = stringBox.get(); // 自动类型转换
// 泛型方法
class Util {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
}
public static <T> T getFirstElement(List<T> list) {
return list.isEmpty() ? null : list.get(0);
}
}
// 钻石运算符(Java 7+)
List<String> list = new ArrayList<>();8.2 泛型边界
java
// extends 上界
class NumberPrinter<T extends Number> {
public void printValue(T num) {
System.out.println(num.doubleValue());
}
}
NumberPrinter<Integer> intPrinter = new NumberPrinter<>();
NumberPrinter<Double> doublePrinter = new NumberPrinter<>();
// NumberPrinter<String> error = new NumberPrinter<>(); // 编译错误
// 多重边界(一个类 + 多个接口)
class MultiBound<T extends Comparable<T> & Serializable> {
// ...
}
// super 下界
void copyFrom(List<? super Integer> dest, List<Integer> src) {
for (Integer i : src) {
dest.add(i);
}
}8.3 通配符
java
// 无界通配符
List<?> list = new ArrayList<String>();
// 可以读取为 Object,不能写入(除 null)
// 上界通配符 - 只能读
void processUpper(List<? extends Number> list) {
for (Number n : list) { // 可以读取
System.out.println(n);
}
// list.add(1); // 编译错误
}
// 下界通配符 - 只能写
void processLower(List<? super Integer> list) {
list.add(1); // 可以写入 Integer
list.add(new Integer(2));
// Number n = list.get(0); // 只能赋值给 Object
}
// PECS 原则:Producer Extends, Consumer Super8.4 类型擦除
java
// 编译后泛型被擦除为原始类型
List<String> ls = new ArrayList<String>();
List<Integer> li = new ArrayList<Integer>();
// 运行时都是 ArrayList
System.out.println(ls.getClass() == li.getClass()); // true
// 限制:
// 1. 不能实例化泛型:new T()
// 2. 不能创建泛型数组:new T[10]
// 3. instanceof 不能使用泛型:obj instanceof List<String>
// 4. 不能创建泛型静态字段9. 反射与注解
9.1 反射基础
获取 Class 对象:
java
// 方式 1:类名.class
Class<String> clazz1 = String.class;
// 方式 2:对象.getClass()
Class<?> clazz2 = "hello".getClass();
// 方式 3:Class.forName()
Class<?> clazz3 = Class.forName("java.util.ArrayList");获取成员信息:
java
Class<?> clazz = MyClass.class;
// 获取所有方法(包括私有)
Method[] methods = clazz.getDeclaredMethods();
// 获取所有字段
Field[] fields = clazz.getDeclaredFields();
// 获取所有构造器
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
// 打印类信息
for (Field f : fields) {
System.out.println(f.getType().getSimpleName() + " " + f.getName());
}
for (Method m : methods) {
System.out.println(m.getReturnType().getSimpleName() + " " + m.getName());
}动态创建对象:
java
// 无参构造
Class<?> clazz = MyClass.class;
Object obj = clazz.getDeclaredConstructor().newInstance();
// 有参构造
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class);
Object obj2 = constructor.newInstance("name", 25);动态调用方法:
java
MyClass obj = new MyClass();
Class<?> clazz = obj.getClass();
// 获取方法
Method method = clazz.getDeclaredMethod("printMessage", String.class);
// 设置可访问(绕过权限检查)
method.setAccessible(true);
// 调用方法
method.invoke(obj, "Hello");
// 调用静态方法
Method staticMethod = clazz.getDeclaredMethod("staticMethod", int.class);
staticMethod.invoke(null, 10); // 静态方法传 null动态访问字段:
java
MyClass obj = new MyClass();
Field field = MyClass.class.getDeclaredField("privateField");
field.setAccessible(true);
// 读取
Object value = field.get(obj);
// 修改
field.set(obj, "newValue");
// 静态字段
Field staticField = MyClass.class.getDeclaredField("STATIC_FIELD");
staticField.set(null, 100); // 静态字段传 null9.2 内置注解
java
@Override
public String toString() {
return "Object";
}
@Deprecated
public void oldMethod() {
// 过时方法
}
@SuppressWarnings({"unchecked", "deprecation"})
public void safeMethod() {
// 抑制警告
}
@FunctionalInterface
interface Calculator {
int compute(int a, int b);
}9.3 自定义注解
java
import java.lang.annotation.*;
// 定义元注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface MyAnnotation {
String value() default "";
int priority() default 0;
String[] tags() default {};
}
// 使用注解
@MyAnnotation(value = "test", priority = 1)
public class MyClass {
@MyAnnotation("important")
public void importantMethod() {
// ...
}
}
// 读取注解
Class<?> clazz = MyClass.class;
// 获取类上的注解
MyAnnotation classAnn = clazz.getAnnotation(MyAnnotation.class);
System.out.println(classAnn.value());
// 获取方法上的注解
Method method = clazz.getMethod("importantMethod");
MyAnnotation methodAnn = method.getAnnotation(MyAnnotation.class);
System.out.println(methodAnn.priority());
// 获取所有注解
Annotation[] annotations = clazz.getAnnotations();
for (Annotation ann : annotations) {
System.out.println(ann.annotationType());
}9.4 元注解说明
| 元注解 | 作用 |
|---|---|
| @Target | 指定注解可使用的目标位置 |
| @Retention | 指定注解的保留策略 |
| @Documented | 注解会被 javadoc 记录 |
| @Inherited | 注解可被子类继承 |
@Target 取值:
ElementType.TYPE- 类、接口、枚举ElementType.FIELD- 字段ElementType.METHOD- 方法ElementType.PARAMETER- 参数ElementType.CONSTRUCTOR- 构造器ElementType.LOCAL_VARIABLE- 局部变量ElementType.ANNOTATION_TYPE- 注解类型
@Retention 取值:
RetentionPolicy.SOURCE- 源码中有效RetentionPolicy.CLASS- 编译后保留(默认)RetentionPolicy.RUNTIME- 运行时可用
10. 函数式编程
10.1 函数式接口
核心函数式接口:
java
// Predicate<T> - 布尔断言
Predicate<String> isEmpty = s -> s.isEmpty();
boolean result = isEmpty.test("");
// Function<T, R> - 转换函数
Function<String, Integer> lengthFunc = String::length;
Integer len = lengthFunc.apply("Hello");
// Consumer<T> - 消费操作
Consumer<String> printer = System.out::println;
printer.accept("Hello");
// Supplier<T> - 提供者
Supplier<LocalDate> dateSupplier = LocalDate::now;
LocalDate today = dateSupplier.get();
// UnaryOperator<T> - 一元运算(Function 特化)
UnaryOperator<Integer> square = x -> x * x;
// BinaryOperator<T> - 二元运算
BinaryOperator<Integer> add = (a, b) -> a + b;
// BiFunction<T, U, R> - 双参数函数
BiFunction<Integer, Integer, Integer> multiply = (a, b) -> a * b;组合函数:
java
Function<Integer, Integer> add10 = x -> x + 10;
Function<Integer, Integer> multiply2 = x -> x * 2;
// andThen - 顺序组合:先 add10 再 multiply2
Function<Integer, Integer> combined1 = add10.andThen(multiply2);
System.out.println(combined1.apply(5)); // (5+10)*2 = 30
// compose - 反向组合:先 multiply2 再 add10
Function<Integer, Integer> combined2 = add10.compose(multiply2);
System.out.println(combined2.apply(5)); // 5*2+10 = 20
// Predicate 组合
Predicate<Integer> greaterThan0 = x -> x > 0;
Predicate<Integer> lessThan100 = x -> x < 100;
Predicate<Integer> range = greaterThan0.and(lessThan100);
Predicate<Integer> outRange = greaterThan0.or(lessThan100).negate();10.2 方法引用
java
// 静态方法引用
Function<String, Integer> parseInt = Integer::parseInt;
// 实例方法引用(特定对象)
String greeting = "Hello";
Supplier<String> upperCase = greeting::toUpperCase;
// 实例方法引用(任意对象)
Function<String, String> toUpperCase = String::toUpperCase;
// 构造器引用
Supplier<ArrayList<String>> arrayListSupplier = ArrayList::new;
Function<String, List<String>> listFactory = Collections::singletonList;10.3 Optional
java
// 创建
Optional<String> empty = Optional.empty();
Optional<String> present = Optional.of("value");
Optional<String> nullable = Optional.ofNullable(maybeNull);
// 链式操作
Optional<String> result = optionalValue
.map(String::toUpperCase)
.filter(s -> s.length() > 5)
.orElse("default");
// 常用方法
String value1 = optionalValue.orElse("default");
String value2 = optionalValue.orElseGet(() -> computeDefault());
String value3 = optionalValue.orElseThrow();
String value4 = optionalValue.orElseThrow(IllegalArgumentException::new);
// 副作用操作
optionalValue.ifPresent(System.out::println);
// 判断
boolean hasValue = optionalValue.isPresent();
boolean isEmpty = optionalValue.isEmpty(); // Java 11+
// 多个 Optional 组合
Optional<String> first = Optional.of("Hello");
Optional<String> second = Optional.empty();
Optional<String> combined = first.or(second); // Java 9+11. 日期时间 API
11.1 核心类
java
// LocalDate - 日期
LocalDate today = LocalDate.now();
LocalDate specific = LocalDate.of(2024, 1, 15);
LocalDate parsed = LocalDate.parse("2024-01-15");
// LocalTime - 时间
LocalTime nowTime = LocalTime.now();
LocalTime specific = LocalTime.of(14, 30, 0);
// LocalDateTime - 日期时间
LocalDateTime nowDT = LocalDateTime.now();
LocalDateTime specific = LocalDateTime.of(2024, 1, 15, 14, 30);
// ZonedDateTime - 带时区
ZonedDateTime beijing = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC);11.2 日期计算
java
LocalDate date = LocalDate.of(2024, 1, 15);
// 加减时间
LocalDate plusDays = date.plusDays(10);
LocalDate minusMonths = date.minusMonths(2);
LocalDate plusYears = date.plusYears(1);
// 获取字段
int year = date.getYear();
Month month = date.getMonth();
int dayOfMonth = date.getDayOfMonth();
DayOfWeek dow = date.getDayOfWeek();
// 修改并返回新实例
LocalDate modified = date.withYear(2025).withDayOfMonth(1);
// 比较
boolean isEqual = date1.isEqual(date2);
boolean isBefore = date1.isBefore(date2);
boolean isAfter = date1.isAfter(date2);11.3 Duration 和 Period
java
// Duration - 基于时间的间隔(小时、分钟、秒)
LocalDateTime start = LocalDateTime.now();
// ... some code
LocalDateTime end = LocalDateTime.now();
Duration duration = Duration.between(start, end);
long seconds = duration.getSeconds();
long millis = duration.toMillis();
// 创建 Duration
Duration d1 = Duration.ofHours(2);
Duration d2 = Duration.ofMinutes(30);
Duration total = d1.plus(d2);
// Period - 基于日期的间隔(年、月、日)
LocalDate birthdate = LocalDate.of(1990, 5, 15);
LocalDate today = LocalDate.now();
Period period = Period.between(birthdate, today);
int years = period.getYears();
int months = period.getMonths();
int days = period.getDays();
// 创建 Period
Period p = Period.ofYears(1).plusMonths(3).plusDays(15);11.4 DateTimeFormatter
java
// 预定义格式
DateTimeFormatter isoDate = DateTimeFormatter.ISO_LOCAL_DATE;
DateTimeFormatter rfc1123 = DateTimeFormatter.RFC_1123_DATE_TIME;
// 自定义格式
DateTimeFormatter custom = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter chinese = DateTimeFormatter.ofPattern("yyyyMMdd", Locale.CHINA);
// 格式化
LocalDateTime dt = LocalDateTime.now();
String formatted = dt.format(custom); // "2024-01-15 14:30:00"
// 解析
LocalDateTime parsed = LocalDateTime.parse("2024-01-15 14:30:00", custom);
// 时区格式化
DateTimeFormatter tzFormatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss z")
.withZone(ZoneId.of("Asia/Shanghai"));
String withZone = ZonedDateTime.now().format(tzFormatter);12. 模块化系统(JPMS)
12.1 module-info.java
java
// 模块定义
module com.myapp.core {
// 导出包
exports com.myapp.core.api;
exports com.myapp.core.service;
// 不导出(包私有)
// com.myapp.core.internal
// 打开包(允许反射访问)
opens com.myapp.core.model;
// 依赖其他模块
requires java.sql;
requires java.logging;
requires com.thirdparty.lib;
// 提供 SPI
provides com.myapp.core.spi.Provider
with com.myapp.core.impl.DefaultProvider;
// 使用服务
uses com.myapp.core.spi.Consumer;
}12.2 自动模块
java
// JAR 放在模块路径上但没有 module-info.java
// 自动模块名从 JAR 文件名推导
// 或使用 Manifest 指定
// Automatic-Module-Name: com.example.mymodule12.3 命令行选项
bash
# 编译模块
javac --module-path modularity \
--add-modules com.myapp.core \
module/src/module-info.java \
module/src/com/myapp/core/*.java
# 运行模块
java --module-path out \
--add-modules com.myapp.core \
com.myapp.core/MainClass
# 查看模块依赖
jlink --list-modules
# 创建自定义运行时镜像
jlink --module-path modularity \
--add-modules java.base,jdk.httpserver \
--output custom-runtime13. Java 版本特性演进
13.1 Java 8(里程碑版本)
Lambda 表达式:
java
// Before
Collections.sort(list, new Comparator<String>() {
public int compare(String a, String b) {
return a.length() - b.length();
}
});
// After
list.sort((a, b) -> a.length() - b.length());
list.sort(Comparator.comparingInt(String::length));Stream API:
java
List<String> result = list.stream()
.filter(s -> s.startsWith("A"))
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());Optional:
java
Optional<String> opt = Optional.ofNullable(getValue());
String value = opt.orElse("default");新的 Date/Time API:
java
LocalDate date = LocalDate.now();
LocalDateTime dt = LocalDateTime.now();
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault());接口默认方法:
java
interface MyInterface {
void abstractMethod();
default void defaultMethod() {
System.out.println("Default implementation");
}
static void staticMethod() {
System.out.println("Static method");
}
}13.2 Java 9
HTTP Client:
java
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/data"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());模块化系统:
java
module my.module {
exports my.package;
requires java.base;
}Private 接口方法:
java
interface MyInterface {
default void publicMethod() {
helper();
}
private void helper() {
// 私有辅助方法
}
}13.3 Java 10
局部变量类型推断:
java
var list = new ArrayList<String>();
var name = "Hello";
var map = Map.of("key", "value");13.4 Java 11
String 新方法:
java
String s = " hello ";
boolean blank = s.isBlank(); // true
String stripped = s.strip(); // "hello"
String lines = "line1\nline2".lines().collect(Collectors.joining(", cant remove them, you'll have to use stripTrailing() instead"));
String repeated = "ab".repeat(3); // "ababab"HTTP Client 标准化:
java
// 从 incubator 移至标准库
import java.net.http.*;变长 Lambda 参数:
java
StringOper s = (var left, var right) -> left + right;13.5 Java 14-17
Records(记录类):
java
// 简洁的数据载体
public record Point(double x, double y) {
// 自动生成:构造函数、getter、equals、hashCode、toString
// 附加方法
public double distanceFromOrigin() {
return Math.sqrt(x * x + y * y);
}
// 紧凑构造函数
public Point {
if (x < 0 || y < 0) {
throw new IllegalArgumentException("坐标不能为负");
}
}
}
// 使用
Point p = new Point(3.0, 4.0);
System.out.println(p.x()); // getterPattern Matching for instanceof:
java
// Java 16 Preview, Java 17 Final
if (obj instanceof String s) {
System.out.println(s.length()); // 自动类型转换
}
// 多条件匹配
if (obj instanceof Point(double x, double y) && x >= 0 && y >= 0) {
System.out.println("第一象限");
}
// switch 中的模式匹配
String describe(Object obj) {
return switch (obj) {
case Integer i -> "Integer: " + i;
case String s -> "String: " + s;
case Point(double x, double y) -> "Point: (" + x + ", " + y + ")";
default -> obj.getClass().getName();
};
}Sealed Classes(密封类):
java
// 限制哪些类可以实现/继承
sealed interface Shape permits Circle, Square, Rectangle { }
final class Circle implements Shape {
double radius;
}
final class Square implements Shape {
double side;
}
// 非最终实现类必须声明为非最终或封闭
non-sealed class Rectangle implements Shape {
double width, height;
}
// 用 switch 穷举匹配
switch (shape) {
case Circle c -> calculateCircleArea(c.radius);
case Square s -> calculateSquareArea(s.side);
case Rectangle r -> calculateRectangleArea(r.width, r.height);
// 不需要 default,编译器检查完整性
}Switch 表达式:
java
// 箭头语法
String result = switch (day) {
case MONDAY, FRIDAY -> "工作日";
case SATURDAY, SUNDAY -> "周末";
default -> {
System.out.println("未知");
yield "其他";
}
};
// 表达式形式
int value = switch (choice) {
case 1 -> 10;
case 2 -> 20;
default -> 0;
};Text Blocks(文本块):
java
// Java 15 Preview, Java 15 Final
String json = """
{
"name": "John",
"age": 30,
"city": "New York"
}
""";
String html = """
<html>
<body>
<h1>Hello World</h1>
</body>
</html>
""";13.6 Java 21(LTS)
虚拟线程:
java
// 轻量级线程,由 JVM 管理
try (ExecutorService executor =
ExecutorService.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10000; i++) {
executor.submit(() -> {
System.out.println("虚拟线程:" + Thread.currentThread().getName());
processRequest();
});
}
}
// 直接启动
Thread.startVirtualThread(() -> {
System.out.println("Running on virtual thread");
});结构化并发:
java
// Java 21 Preview
StructuredTaskScope scope = new StructuredTaskScope.ShutdownOnFailure();
Future<Result> f1 = scope.fork(() -> task1());
Future<Result> f2 = scope.fork(() -> task2());
try {
scope.join(); // 等待所有任务完成
scope.throwIfFailed(); // 如有失败则抛出异常
} finally {
scope.close();
}Record Pattern:
java
record Address(String city, String zip) {}
record Person(String name, Address address) {}
Person p = new Person("Alice", new Address("NYC", "10001"));
// 解构模式匹配
if (p instanceof Person(String name, Address("NYC", String zip))) {
System.out.println(name + " lives in NYC with zip " + zip);
}
// switch 中使用
String describe(Person p) {
return switch (p) {
case Person(String name, Address("NYC", _)) -> name + " is in NYC";
case Person(_, Address(String city, _)) -> "Address city: " + city;
case Person(String name, _) -> "Name: " + name;
};
}Sequenced Collections:
java
// List 和 Deque 的新子接口
SequencedList<String> seqList = SequencedList.of("a", "b", "c");
SequencedSet<String> seqSet = SequencedSet.of("a", "b", "c");
String first = seqList.firstElement();
String last = seqList.lastElement();
SequencedList<String> reversed = seqList.reversed();String 模板(Preview):
java
// Java 21 Preview
String name = "World";
int age = 25;
String greeting = STR."Hello, \{name}!";
String info = STR."""
Name: \{name}
Age: \{age}
""";Foreign Function & Memory API(Preview):
java
// 安全地访问 JVM 外部的内存和调用本地函数
Arena arena = Arena.ofShared();
SymbolLookup lookup = SymbolLookup.loaderLookup();
MemorySegment segment = arena.allocate(256);Vector API(Incubating):
java
// SIMD 向量运算
FloatVector v1 = FloatVector.fromArray(VirtualStackLayout.SEQUENCE_SPEC,
new float[]{1, 2, 3, 4}, 0);
FloatVector v2 = v1.add(1.0f);14. 性能调优与监控
14.1 JVM 启动参数
bash
# 堆内存
-Xms4g -Xmx4g # 固定堆大小,避免扩容开销
-XX:MetaspaceSize=256m # Metaspace 初始
-XX:MaxMetaspaceSize=512m # Metaspace 最大
-Xss2m # 每个线程栈大小
# GC 选择
-XX:+UseG1GC # G1 收集器(JDK9+ 默认)
-XX:+UseZGC # ZGC(超低停顿)
-XX:MaxGCPauseMillis=200 # G1 目标停顿时间
# GC 日志
-Xlog:gc*:file=gc.log:time,uptime,level,tags
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps
# OOM 处理
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/log/app/heap.hprof
# JIT 编译
-XX:+UnlockDiagnosticVMOptions
-XX:CompileCommand=print,*ClassName.methodName
-XX:CompileThreshold=10000 # 方法调用次数阈值
# 调试
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=500514.2 诊断工具
jps - 进程列表:
bash
jps -lvm # 显示 JVM 参数
jps -v # 显示参数
jps -m # 显示 main 方法和参数jstat - GC 统计:
bash
# GC 统计
jstat -gc <pid> 1000 10 # 每 1 秒输出一次,共 10 次
# 类加载统计
jstat -class <pid> 1000
# 代码缓存统计
jstat -gccapacity <pid>jmap - 内存分析:
bash
# 堆转储
jmap -dump:live,format=b,file=heap.hprof <pid>
# 堆统计
jmap -histo:live <pid> | head -20
# 打印 VM 参数
jmap -dump:format=b <pid>jstack - 线程堆栈:
bash
# 线程堆栈
jstack <pid>
# 只打印死锁
jstack -l <pid> | grep -A 10 "Deadlock"
# 输出到文件
jstack <pid> > thread_dump.txtjinfo - VM 配置:
bash
# 查看所有参数
jinfo <pid>
# 查看特定参数
jinfo -flag MaxHeapSize <pid>
# 动态修改参数
jinfo -flag:+PrintGCDetails <pid>jcmd - 诊断命令:
bash
# 列出进程
jcmd
# 线程堆栈
jcmd <pid> Thread.print
# GC 信息
jcmd <pid> GC.heap_info
# 堆转储
jcmd <pid> GC.heap_dump /path/dump.hprof
# 混合模式编译列表
jcmd <pid> VM.compileVisualVM:
# 图形化监控工具
# 功能:CPU 分析、内存分析、线程分析、GC 监控、堆转储Java Flight Recorder (JFR):
bash
# 启动录制
jcmd <pid> JFR.start duration=5m filename=recording.jfr
# 停止录制
jcmd <pid> JFR.stop
# JDK 11+ 内置支持
java -XX:StartFlightRecording=duration=5m,filename=recording.jfr -jar app.jar14.3 性能分析最佳实践
- 建立基线: 记录正常运行的性能指标
- 渐进式优化: 每次只改变一个变量
- 关注热点: 优先优化占用 80% 资源的 20% 代码
- 避免过早优化: 先确保正确性,再考虑性能
- 使用生产环境数据: 测试环境与生产环境保持一致
15. 安全机制
15.1 SSL/TLS
服务器端:
java
char[] password = "password".toCharArray();
KeyStore keyStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream("server.keystore")) {
keyStore.load(fis, password);
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keyStore, password);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);
SSLServerSocket serverSocket =
(SSLServerSocket) sslContext.getServerSocketFactory()
.createServerSocket(8443);客户端:
java
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(new FileInputStream("truststore.jks"), password);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(sslContext.getSocketFactory());15.2 加密
对称加密(AES):
java
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey secretKey = keyGen.generateKey();
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal(plainText.getBytes());
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decrypted = cipher.doFinal(encrypted);非对称加密(RSA):
java
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
// 公钥加密
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
byte[] encrypted = cipher.doFinal(plainText.getBytes());
// 私钥解密
cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
byte[] decrypted = cipher.doFinal(encrypted);消息摘要(SHA-256):
java
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(data);
// 转为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
hexString.append(String.format("%02x", b));
}
String hash = hexString.toString();15.3 安全最佳实践
- 密钥管理: 使用专门的密钥管理系统,不要硬编码
- 传输加密: 始终使用 HTTPS/TLS
- 输入验证: 对所有输入进行严格验证
- 最小权限: 遵循最小权限原则
- 安全随机: 使用 SecureRandom 而非 Random
- 密码存储: 使用 bcrypt/scrypt/Argon2 哈希密码
16. 设计模式
16.1 单例模式
java
// 饿汉式
public class Singleton1 {
private static final Singleton1 INSTANCE = new Singleton1();
private Singleton1() {}
public static Singleton1 getInstance() { return INSTANCE; }
}
// 懒汉式(双重检查锁定)
public class Singleton2 {
private static volatile Singleton2 instance;
private Singleton2() {}
public static Singleton2 getInstance() {
if (instance == null) {
synchronized (Singleton2.class) {
if (instance == null) {
instance = new Singleton2();
}
}
}
return instance;
}
}
// 静态内部类
public class Singleton3 {
private Singleton3() {}
private static class Holder {
static final Singleton3 INSTANCE = new Singleton3();
}
public static Singleton3 getInstance() {
return Holder.INSTANCE;
}
}
// 枚举(推荐)
public enum Singleton4 {
INSTANCE;
public void doSomething() { }
}16.2 工厂模式
java
interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() { System.out.println("Drawing circle"); }
}
class Rectangle implements Shape {
public void draw() { System.out.println("Drawing rectangle"); }
}
class ShapeFactory {
public Shape getShape(String type) {
switch (type.toLowerCase()) {
case "circle": return new Circle();
case "rectangle": return new Rectangle();
default: throw new IllegalArgumentException("Unknown shape");
}
}
}16.3 建造者模式
java
public class Person {
private final String name;
private final int age;
private final String email;
private final String phone;
private Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.email = builder.email;
this.phone = builder.phone;
}
public static class Builder {
private final String name;
private final int age;
private String email;
private String phone;
public Builder(String name, int age) {
this.name = name;
this.age = age;
}
public Builder email(String email) {
this.email = email;
return this;
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Person build() {
return new Person(this);
}
}
}
// 使用
Person person = new Person.Builder("Alice", 30)
.email("alice@example.com")
.phone("123-4567")
.build();16.4 策略模式
java
interface PaymentStrategy {
void pay(double amount);
}
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public void pay(double amount) {
System.out.println("Paid " + amount + " using credit card");
}
}
class PayPalPayment implements PaymentStrategy {
private String email;
public void pay(double amount) {
System.out.println("Paid " + amount + " using PayPal");
}
}
class Context {
private PaymentStrategy strategy;
public void setStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void checkout(double amount) {
strategy.pay(amount);
}
}
// 使用枚举实现策略
enum PaymentStrategyEnum {
CREDIT_CARD {
public void pay(double amount) {
System.out.println("Credit card payment: " + amount);
}
},
PAYPAL {
public void pay(double amount) {
System.out.println("PayPal payment: " + amount);
}
};
abstract void pay(double amount);
}16.5 观察者模式
java
// Subject
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
// Observer
interface Observer {
void update(String message);
}
// Concrete Subject
class NewsAgency implements Subject {
private List<Observer> observers = new ArrayList<>();
private String news;
public void attach(Observer o) { observers.add(o); }
public void detach(Observer o) { observers.remove(o); }
public void setNews(String news) {
this.news = news;
notifyObservers();
}
public void notifyObservers() {
for (Observer o : observers) {
o.update(news);
}
}
}
// Concrete Observer
class Newspaper implements Observer {
private String name;
public Newspaper(String name) { this.name = name; }
public void update(String news) {
System.out.println(name + " received: " + news);
}
}
// Java 内置实现
class MyListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
// 处理事件
}
}附录
A. 常用命令
bash
# 编译
javac -encoding UTF-8 -source 17 -target 17 Main.java
# 运行
java -cp . Main
# 打包
jar cvfm app.jar manifest.mf *.class
# 查看类文件
javap -c -v MyClass
# 反编译
jad MyClass.classB. 参考资料
本文档最后更新:2024 年涵盖 Java 8 至 Java 21 主要特性
