1. Java 基础语法
1.1 数据类型和变量
Java 是强类型语言,分为基本数据类型和引用数据类型。
java
// 基本数据类型
public class DataTypeExample {
public static void main(String[] args) {
// 整型
byte b = 127; // 8位,-128到127
short s = 32767; // 16位,-32768到32767
int i = 2147483647; // 32位,约21亿
long l = 9223372036854775807L; // 64位,L后缀
// 浮点型
float f = 3.14f; // 32位,f后缀
double d = 3.14159; // 64位,默认浮点类型
// 字符型
char c = 'A'; // 16位Unicode字符
// 布尔型
boolean flag = true; // true或false
System.out.println("基本数据类型示例:" + i + ", " + d + ", " + flag);
}
}
1.2 运算符
java
public class OperatorExample {
public static void main(String[] args) {
int a = 10, b = 5;
// 算术运算符
System.out.println("a + b = " + (a + b));
System.out.println("a - b = " + (a - b));
System.out.println("a * b = " + (a * b));
System.out.println("a / b = " + (a / b));
System.out.println("a % b = " + (a % b));
// 比较运算符
System.out.println("a > b = " + (a > b));
System.out.println("a == b = " + (a == b));
// 逻辑运算符
boolean x = true, y = false;
System.out.println("x && y = " + (x && y));
System.out.println("x || y = " + (x || y));
System.out.println("!x = " + (!x));
// 三元运算符
int max = (a > b) ? a : b;
System.out.println("max = " + max);
}
}
1.3 控制流程
java
public class ControlFlowExample {
public static void main(String[] args) {
int score = 85;
// if-else 语句
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
// switch 语句
switch (score / 10) {
case 10:
case 9:
System.out.println("A等级");
break;
case 8:
System.out.println("B等级");
break;
case 7:
System.out.println("C等级");
break;
default:
System.out.println("D等级");
}
// for 循环
for (int i = 1; i <= 5; i++) {
System.out.println("循环第" + i + "次");
}
// while 循环
int j = 1;
while (j <= 3) {
System.out.println("while循环第" + j + "次");
j++;
}
// 增强for循环
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
System.out.println("数组元素:" + num);
}
}
}
2. 面向对象编程
2.1 类和对象
java
// 定义一个简单的类
public class Person {
// 成员变量(属性)
private String name;
private int age;
private String gender;
// 构造方法
public Person() {
// 无参构造方法
}
public Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
// Getter和Setter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0 && age < 150) {
this.age = age;
} else {
System.out.println("年龄不合法");
}
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
// 成员方法
public void introduce() {
System.out.println("我是" + name + ",今年" + age + "岁,性别是" + gender);
}
// 重写toString方法
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", gender='" + gender + "'}";
}
}
// 测试类
class PersonTest {
public static void main(String[] args) {
// 创建对象
Person person1 = new Person();
person1.setName("张三");
person1.setAge(25);
person1.setGender("男");
person1.introduce();
Person person2 = new Person("李四", 30, "女");
System.out.println(person2.toString());
}
}
2.2 继承、封装、多态
java
// 父类 - 动物
public class Animal {
protected String name;
protected int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// 封装 - Getter和Setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
// 普通方法,同样可以被子类重写
public void eat() {
System.out.println(name + "正在吃东西");
}
// 这个方法将被子类重写,以演示多态
public void makeSound() {
System.out.println("动物发出声音");
}
}
// 子类 - 狗
class Dog extends Animal {
private String breed; // 品种
public Dog(String name, int age, String breed) {
super(name, age); // 调用父类构造方法
this.breed = breed;
}
// 重写父类方法(多态体现)
@Override
public void makeSound() {
System.out.println(name + "汪汪叫");
}
// 子类特有方法
public void wagTail() {
System.out.println(name + "摇尾巴");
}
public String getBreed() { return breed; }
public void setBreed(String breed) { this.breed = breed; }
}
// 子类 - 猫
class Cat extends Animal {
private boolean isIndoor; // 是否室内猫
public Cat(String name, int age, boolean isIndoor) {
super(name, age);
this.isIndoor = isIndoor;
}
// 重写父类方法
@Override
public void makeSound() {
System.out.println(name + "喵喵叫");
}
public boolean isIndoor() { return isIndoor; }
public void setIndoor(boolean indoor) { isIndoor = indoor; }
}
// 测试多态
class PolymorphismTest {
public static void main(String[] args) {
// 多态 - 父类引用指向子类对象
Animal animal1 = new Dog("旺财", 3, "金毛");
Animal animal2 = new Cat("咪咪", 2, true);
// 调用重写的方法 - 体现多态
animal1.makeSound(); // 输出:旺财汪汪叫
animal2.makeSound(); // 输出:咪咪喵喵叫
// 向下转型(需要类型检查)
if (animal1 instanceof Dog) {
Dog dog = (Dog) animal1;
dog.wagTail(); // 调用子类特有方法
}
}
}
2.3 抽象类和接口
java
// 抽象类 - 形状
public abstract class Shape {
protected String color;
public Shape(String color) {
this.color = color;
}
// 具体方法
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
// 抽象方法 - 子类必须实现
public abstract double getArea();
public abstract double getPerimeter();
// 可以有具体方法
public void displayInfo() {
System.out.println("这是一个" + color + "色的形状");
}
}
// 具体类 - 矩形
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(String color, double width, double height) {
super(color);
this.width = width;
this.height = height;
}
@Override
public double getArea() {
return width * height;
}
@Override
public double getPerimeter() {
return 2 * (width + height);
}
public double getWidth() { return width; }
public void setWidth(double width) { this.width = width; }
public double getHeight() { return height; }
public void setHeight(double height) { this.height = height; }
}
// 接口 - 可移动的
interface Movable {
void move(int x, int y);
default void showPosition() { // Java 8 默认方法
System.out.println("当前位置:(" + getX() + ", " + getY() + ")");
}
// 抽象方法
int getX();
int getY();
}
// 接口 - 可绘制的
interface Drawable {
void draw();
static void printSupportedShapes() { // Java 8 静态方法
System.out.println("支持绘制的形状:圆形、矩形、三角形");
}
}
// 实现多个接口的类
class MovableRectangle extends Rectangle implements Movable, Drawable {
private int x, y; // 位置坐标
public MovableRectangle(String color, double width, double height, int x, int y) {
super(color, width, height);
this.x = x;
this.y = y;
}
@Override
public void move(int x, int y) {
this.x = x;
this.y = y;
System.out.println("移动到位置:(" + x + ", " + y + ")");
}
@Override
public void draw() {
System.out.println("绘制一个" + getColor() + "色的矩形,宽:" +
getWidth() + ",高:" + getHeight());
}
@Override
public int getX() { return x; }
@Override
public int getY() { return y; }
}
// 测试抽象类和接口
class AbstractInterfaceTest {
public static void main(String[] args) {
// 使用抽象类
Rectangle rect = new Rectangle("红色", 5.0, 3.0);
System.out.println("矩形面积:" + rect.getArea());
System.out.println("矩形周长:" + rect.getPerimeter());
// 使用接口
MovableRectangle movableRect = new MovableRectangle("蓝色", 4.0, 6.0, 0, 0);
movableRect.draw();
movableRect.move(10, 20);
movableRect.showPosition();
// 调用接口静态方法
Drawable.printSupportedShapes();
}
}
3. 集合框架
3.1 List 集合
java
import java.util.*;
public class ListExample {
public static void main(String[] args) {
// ArrayList - 动态数组
List<String> arrayList = new ArrayList<>();
arrayList.add("苹果");
arrayList.add("香蕉");
arrayList.add("橙子");
arrayList.add(1, "葡萄"); // 在指定位置插入
System.out.println("ArrayList: " + arrayList);
System.out.println("第2个元素: " + arrayList.get(1));
System.out.println("元素个数: " + arrayList.size());
// LinkedList - 双向链表
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("第一个");
linkedList.add("第二个");
linkedList.addFirst("开头");
linkedList.addLast("结尾");
System.out.println("LinkedList: " + linkedList);
System.out.println("第一个元素: " + linkedList.getFirst());
System.out.println("最后一个元素: " + linkedList.getLast());
// 遍历方式
System.out.println("=== 遍历 ArrayList ===");
// 1. 增强for循环
for (String fruit : arrayList) {
System.out.println(fruit);
}
// 2. 迭代器
Iterator<String> iterator = arrayList.iterator();
while (iterator.hasNext()) {
System.out.println("迭代器: " + iterator.next());
}
// 3. Lambda表达式 (Java 8+)
arrayList.forEach(System.out::println);
}
}
3.2 Map 集合
java
import java.util.*;
public class MapExample {
public static void main(String[] args) {
// HashMap - 哈希映射
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("张三", 25);
hashMap.put("李四", 30);
hashMap.put("王五", 28);
hashMap.put("张三", 26); // 会覆盖原来的值
System.out.println("HashMap: " + hashMap);
System.out.println("张三的年龄: " + hashMap.get("张三"));
System.out.println("是否包含键'李四': " + hashMap.containsKey("李四"));
System.out.println("是否包含值30: " + hashMap.containsValue(30));
// 遍历Map
System.out.println("=== 遍历 HashMap ===");
// 1. 遍历键值对
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// 2. 遍历键
for (String key : hashMap.keySet()) {
System.out.println(key + " -> " + hashMap.get(key));
}
// 3. 遍历值
for (Integer value : hashMap.values()) {
System.out.println("年龄: " + value);
}
// LinkedHashMap - 保持插入顺序
Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put("第一", 1);
linkedHashMap.put("第二", 2);
linkedHashMap.put("第三", 3);
System.out.println("LinkedHashMap: " + linkedHashMap);
// TreeMap - 按键排序
Map<String, Integer> treeMap = new TreeMap<>();
treeMap.put("banana", 2);
treeMap.put("apple", 1);
treeMap.put("cherry", 3);
System.out.println("TreeMap: " + treeMap);
}
}
3.3 Set 集合
java
import java.util.*;
public class SetExample {
public static void main(String[] args) {
// HashSet - 无序,不允许重复
Set<String> hashSet = new HashSet<>();
hashSet.add("Java");
hashSet.add("Python");
hashSet.add("C++");
hashSet.add("Java"); // 重复元素不会添加
hashSet.add("JavaScript");
System.out.println("HashSet: " + hashSet);
System.out.println("元素个数: " + hashSet.size());
System.out.println("是否包含'Python': " + hashSet.contains("Python"));
// LinkedHashSet - 保持插入顺序
Set<String> linkedHashSet = new LinkedHashSet<>();
linkedHashSet.add("第一个");
linkedHashSet.add("第二个");
linkedHashSet.add("第三个");
System.out.println("LinkedHashSet: " + linkedHashSet);
// TreeSet - 排序Set
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(5);
treeSet.add(2);
treeSet.add(8);
treeSet.add(1);
System.out.println("TreeSet: " + treeSet);
// Set的常用操作
Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
Set<Integer> set2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8));
// 并集
Set<Integer> union = new HashSet<>(set1);
union.addAll(set2);
System.out.println("并集: " + union);
// 交集
Set<Integer> intersection = new HashSet<>(set1);
intersection.retainAll(set2);
System.out.println("交集: " + intersection);
// 差集
Set<Integer> difference = new HashSet<>(set1);
difference.removeAll(set2);
System.out.println("差集: " + difference);
}
}
4. 异常处理
4.1 异常基础
java
public class ExceptionExample {
public static void main(String[] args) {
// try-catch-finally 基本用法
try {
int result = 10 / 0; // 会抛出 ArithmeticException
System.out.println("结果: " + result);
} catch (ArithmeticException e) {
System.out.println("捕获到算术异常: " + e.getMessage());
} finally {
System.out.println("finally块总是执行");
}
// 多重catch
try {
String str = null;
System.out.println(str.length()); // 会抛出 NullPointerException
int[] arr = new int[3];
System.out.println(arr[5]); // 会抛出 ArrayIndexOutOfBoundsException
} catch (NullPointerException e) {
System.out.println("空指针异常: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界异常: " + e.getMessage());
} catch (Exception e) {
// 捕获所有其他异常
System.out.println("其他异常: " + e.getMessage());
}
// try-with-resources (Java 7+)
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("请输入一个数字:");
// int num = scanner.nextInt();
// System.out.println("输入的数字是: " + num);
} catch (Exception e) {
System.out.println("输入异常: " + e.getMessage());
}
// Scanner会自动关闭
// 自定义异常测试
try {
validateAge(-5);
} catch (InvalidAgeException e) {
System.out.println("自定义异常: " + e.getMessage());
}
}
public static void validateAge(int age) throws InvalidAgeException {
if (age < 0) {
throw new InvalidAgeException("年龄不能为负数: " + age);
}
if (age > 150) {
throw new InvalidAgeException("年龄不能超过150: " + age);
}
System.out.println("年龄合法: " + age);
}
}
// 自定义异常类
class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
4.2 异常处理最佳实践
java
public class ExceptionBestPractice {
// 1. 不要忽略异常
public void badPractice() {
try {
// 一些可能出错的代码
int result = 10 / 0;
} catch (Exception e) {
// 错误做法:什么都不做
}
}
// 2. 正确做法:记录异常或重新抛出
public void goodPractice() throws Exception {
try {
// 一些可能出错的代码
int result = 10 / 0;
} catch (ArithmeticException e) {
// 记录日志
System.err.println("发生算术异常: " + e.getMessage());
// 重新抛出或抛出自定义异常
throw new Exception("计算过程中发生错误", e);
}
}
// 3. 异常链
public void exceptionChaining() {
try {
// 模拟数据库操作
performDatabaseOperation();
} catch (DatabaseException e) {
// 包装异常并重新抛出
throw new ServiceException("服务调用失败", e);
}
}
private void performDatabaseOperation() throws DatabaseException {
throw new DatabaseException("数据库连接失败");
}
}
// 自定义异常类层次
class ServiceException extends RuntimeException {
public ServiceException(String message) {
super(message);
}
public ServiceException(String message, Throwable cause) {
super(message, cause);
}
}
class DatabaseException extends Exception {
public DatabaseException(String message) {
super(message);
}
}
5. 多线程
5.1 线程基础
java
// 1. 继承 Thread 类
class MyThread extends Thread {
private String threadName;
public MyThread(String name) {
this.threadName = name;
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(threadName + " 执行第 " + i + " 次");
try {
Thread.sleep(1000); // 暂停1秒
} catch (InterruptedException e) {
System.out.println(threadName + " 被中断");
return;
}
}
System.out.println(threadName + " 执行完毕");
}
}
// 2. 实现 Runnable 接口
class MyRunnable implements Runnable {
private String taskName;
public MyRunnable(String name) {
this.taskName = name;
}
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(taskName + " 处理任务 " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
System.out.println(taskName + " 任务完成");
}
}
// 3. 使用 Lambda 表达式
public class ThreadExample {
public static void main(String[] args) {
// 方式1:继承Thread类
MyThread thread1 = new MyThread("线程1");
MyThread thread2 = new MyThread("线程2");
thread1.start();
thread2.start();
// 方式2:实现Runnable接口
Thread thread3 = new Thread(new MyRunnable("任务1"));
Thread thread4 = new Thread(new MyRunnable("任务2"));
thread3.start();
thread4.start();
// 方式3:Lambda表达式
Thread thread5 = new Thread(() -> {
for (int i = 1; i <= 3; i++) {
System.out.println("Lambda线程执行第 " + i + " 次");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
});
thread5.start();
// 等待所有线程执行完毕
try {
thread1.join();
thread2.join();
thread3.join();
thread4.join();
thread5.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("所有线程执行完毕");
}
}
5.2 线程同步
java
// 线程安全的计数器
class SafeCounter {
private int count = 0;
// 方法同步 - synchronized 关键字
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
// 代码块同步
public void decrement() {
synchronized (this) {
count--;
}
}
}
// 生产者消费者示例
class ProducerConsumerExample {
private static final int BUFFER_SIZE = 10;
private final int[] buffer = new int[BUFFER_SIZE];
private int count = 0;
private int in = 0; // 生产位置
private int out = 0; // 消费位置
// 生产者
class Producer implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 20; i++) {
try {
produce(i);
Thread.sleep(100); // 模拟生产时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
private void produce(int item) throws InterruptedException {
synchronized (this) {
// 等待缓冲区有空间
while (count == BUFFER_SIZE) {
wait();
}
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
count++;
System.out.println("生产: " + item + ", 缓冲区大小: " + count);
notifyAll(); // 通知等待的消费者
}
}
}
// 消费者
class Consumer implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
int item = consume();
System.out.println("消费: " + item);
Thread.sleep(150); // 模拟消费时间
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
private int consume() throws InterruptedException {
synchronized (this) {
// 等待缓冲区有数据
while (count == 0) {
wait();
}
int item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count--;
notifyAll(); // 通知等待的生产者
return item;
}
}
}
public static void main(String[] args) {
ProducerConsumerExample example = new ProducerConsumerExample();
Thread producerThread = new Thread(example.new Producer());
Thread consumerThread = new Thread(example.new Consumer());
producerThread.start();
consumerThread.start();
try {
producerThread.join();
consumerThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("生产消费完成");
}
}
5.3 线程池
java
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
// 1. 创建固定大小的线程池
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
// 提交任务
for (int i = 1; i <= 5; i++) {
final int taskId = i;
fixedThreadPool.submit(() -> {
System.out.println("任务 " + taskId + " 由线程 " +
Thread.currentThread().getName() + " 执行");
try {
Thread.sleep(2000); // 模拟任务执行
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("任务 " + taskId + " 执行完毕");
});
}
// 2. 创建缓存线程池
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
// 提交带返回值的任务
Future<String> future = cachedThreadPool.submit(() -> {
Thread.sleep(1000);
return "异步任务结果";
});
try {
// 获取异步结果
String result = future.get(3, TimeUnit.SECONDS);
System.out.println("异步结果: " + result);
} catch (Exception e) {
System.out.println("获取结果异常: " + e.getMessage());
}
// 3. 创建单线程执行器
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
singleThreadExecutor.submit(() -> {
System.out.println("单线程任务执行");
});
// 4. 自定义线程池
ThreadPoolExecutor customThreadPool = new ThreadPoolExecutor(
2, // 核心线程数
4, // 最大线程数
60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new LinkedBlockingQueue<>(100), // 工作队列
new ThreadFactory() { // 线程工厂
private int counter = 0;
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "CustomThread-" + counter++);
}
},
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
// 提交任务到自定义线程池
for (int i = 1; i <= 3; i++) {
final int taskId = i;
customThreadPool.submit(() -> {
System.out.println("自定义线程池任务 " + taskId +
" 由 " + Thread.currentThread().getName() + " 执行");
});
}
// 关闭线程池
fixedThreadPool.shutdown();
cachedThreadPool.shutdown();
singleThreadExecutor.shutdown();
customThreadPool.shutdown();
try {
// 等待所有任务完成
if (!fixedThreadPool.awaitTermination(10, TimeUnit.SECONDS)) {
fixedThreadPool.shutdownNow();
}
} catch (InterruptedException e) {
fixedThreadPool.shutdownNow();
Thread.currentThread().interrupt();
}
System.out.println("所有线程池已关闭");
}
}
6. IO/NIO
6.1 传统 IO
java
import java.io.*;
import java.util.Scanner;
public class IOExample {
public static void main(String[] args) {
// 1. 文件读写 - 字节流
fileByteIO();
// 2. 文件读写 - 字符流
fileCharacterIO();
// 3. 缓冲流
bufferedIO();
// 4. 对象序列化
objectSerialization();
}
// 字节流操作
public static void fileByteIO() {
String fileName = "test.txt";
// 写入文件
try (FileOutputStream fos = new FileOutputStream(fileName)) {
String content = "Hello, Java IO!";
fos.write(content.getBytes());
System.out.println("字节流写入完成");
} catch (IOException e) {
System.err.println("写入文件异常: " + e.getMessage());
}
// 读取文件
try (FileInputStream fis = new FileInputStream(fileName)) {
byte[] buffer = new byte[1024];
int bytesRead = fis.read(buffer);
String content = new String(buffer, 0, bytesRead);
System.out.println("字节流读取内容: " + content);
} catch (IOException e) {
System.err.println("读取文件异常: " + e.getMessage());
}
}
// 字符流操作
public static void fileCharacterIO() {
String fileName = "test_char.txt";
// 写入文件
try (FileWriter writer = new FileWriter(fileName)) {
writer.write("你好,Java字符流!\n");
writer.write("这是第二行内容。");
System.out.println("字符流写入完成");
} catch (IOException e) {
System.err.println("字符流写入异常: " + e.getMessage());
}
// 读取文件
try (FileReader reader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(reader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println("读取行: " + line);
}
} catch (IOException e) {
System.err.println("字符流读取异常: " + e.getMessage());
}
}
// 缓冲流提高性能
public static void bufferedIO() {
String fileName = "buffered_test.txt";
// 使用缓冲输出流
try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
for (int i = 1; i <= 1000; i++) {
writer.write("这是第 " + i + " 行数据\n");
}
writer.flush(); // 强制刷新缓冲区
System.out.println("缓冲写入完成");
} catch (IOException e) {
System.err.println("缓冲写入异常: " + e.getMessage());
}
// 使用缓冲输入流
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
int lineCount = 0;
while ((line = reader.readLine()) != null && lineCount < 5) {
System.out.println("读取: " + line);
lineCount++;
}
} catch (IOException e) {
System.err.println("缓冲读取异常: " + e.getMessage());
}
}
// 对象序列化
public static void objectSerialization() {
String fileName = "person.ser";
Person person = new Person("张三", 25, "男");
// 序列化对象
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
oos.writeObject(person);
System.out.println("对象序列化完成");
} catch (IOException e) {
System.err.println("序列化异常: " + e.getMessage());
}
// 反序列化对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
Person deserializedPerson = (Person) ois.readObject();
System.out.println("反序列化对象: " + deserializedPerson);
} catch (IOException | ClassNotFoundException e) {
System.err.println("反序列化异常: " + e.getMessage());
}
}
}
// 可序列化的Person类
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private String gender;
public Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", gender='" + gender + "'}";
}
}
6.2 NIO (New IO)
java
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
public class NIOExample {
public static void main(String[] args) {
// 1. Path 和 Files
pathAndFilesExample();
// 2. 文件通道操作
fileChannelExample();
// 3. 目录操作
directoryExample();
}
// Path 和 Files 示例
public static void pathAndFilesExample() {
try {
// 创建 Path 对象
Path path = Paths.get("nio_test.txt");
// 写入文件
String content = "Hello, NIO!\n这是第二行内容。";
Files.write(path, content.getBytes(StandardCharsets.UTF_8));
System.out.println("NIO写入完成");
// 读取文件
byte[] bytes = Files.readAllBytes(path);
String readContent = new String(bytes, StandardCharsets.UTF_8);
System.out.println("NIO读取内容: " + readContent);
// 按行读取
System.out.println("按行读取:");
Files.lines(path).forEach(System.out::println);
// 检查文件属性
if (Files.exists(path)) {
System.out.println("文件大小: " + Files.size(path) + " 字节");
System.out.println("是否为目录: " + Files.isDirectory(path));
}
} catch (IOException e) {
System.err.println("NIO操作异常: " + e.getMessage());
}
}
// 文件通道示例
public static void fileChannelExample() {
String fileName = "channel_test.txt";
try {
// 写入数据到文件
Path path = Paths.get(fileName);
try (FileChannel channel = FileChannel.open(path,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.TRUNCATE_EXISTING)) {
String data = "这是通过FileChannel写入的数据";
ByteBuffer buffer = ByteBuffer.wrap(data.getBytes(StandardCharsets.UTF_8));
channel.write(buffer);
System.out.println("通过Channel写入完成");
}
// 从文件读取数据
try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = channel.read(buffer);
if (bytesRead > 0) {
buffer.flip(); // 切换到读模式
byte[] bytes = new byte[bytesRead];
buffer.get(bytes);
String content = new String(bytes, StandardCharsets.UTF_8);
System.out.println("通过Channel读取: " + content);
}
}
} catch (IOException e) {
System.err.println("Channel操作异常: " + e.getMessage());
}
}
// 目录操作示例
public static void directoryExample() {
try {
// 创建目录
Path dirPath = Paths.get("test_directory");
if (!Files.exists(dirPath)) {
Files.createDirectory(dirPath);
System.out.println("目录创建完成: " + dirPath);
}
// 在目录中创建文件
Path filePath = dirPath.resolve("test_file.txt");
Files.write(filePath, "测试文件内容".getBytes(StandardCharsets.UTF_8));
// 遍历目录
System.out.println("目录内容:");
Files.list(dirPath).forEach(System.out::println);
// 递归遍历目录
System.out.println("递归目录内容:");
Files.walk(dirPath, 2) // 最大深度为2
.forEach(System.out::println);
// 删除文件和目录
Files.deleteIfExists(filePath);
System.out.println("删除文件: " + filePath);
} catch (IOException e) {
System.err.println("目录操作异常: " + e.getMessage());
}
}
}
7. 数据库操作
7.1 JDBC 基础
java
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
// 用户实体类
class User {
private int id;
private String name;
private String email;
private int age;
// 构造方法
public User() {}
public User(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
public User(int id, String name, String email, int age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
// Getter和Setter方法
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "', email='" + email + "', age=" + age + "}";
}
}
// 数据库连接工具类
class DatabaseUtil {
private static final String URL = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC";
private static final String USERNAME = "root";
private static final String PASSWORD = "password";
static {
try {
// 加载MySQL驱动
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException("加载数据库驱动失败", e);
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
// 关闭资源的工具方法
public static void closeQuietly(AutoCloseable... resources) {
for (AutoCloseable resource : resources) {
if (resource != null) {
try {
resource.close();
} catch (Exception e) {
// 静默关闭,忽略异常
}
}
}
}
}
// 用户DAO类
class UserDAO {
// 创建用户表
public void createTable() {
String sql = """
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
age INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""";
try (Connection conn = DatabaseUtil.getConnection();
Statement stmt = conn.createStatement()) {
stmt.execute(sql);
System.out.println("用户表创建成功");
} catch (SQLException e) {
System.err.println("创建表失败: " + e.getMessage());
}
}
// 插入用户
public boolean insertUser(User user) {
String sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getEmail());
pstmt.setInt(3, user.getAge());
int rowsAffected = pstmt.executeUpdate();
System.out.println("插入用户成功,影响行数: " + rowsAffected);
return rowsAffected > 0;
} catch (SQLException e) {
System.err.println("插入用户失败: " + e.getMessage());
return false;
}
}
// 根据ID查询用户
public User getUserById(int id) {
String sql = "SELECT * FROM users WHERE id = ?";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
ResultSet rs = pstmt.executeQuery();
if (rs.next()) {
return new User(
rs.getInt("id"),
rs.getString("name"),
rs.getString("email"),
rs.getInt("age")
);
}
} catch (SQLException e) {
System.err.println("查询用户失败: " + e.getMessage());
}
return null;
}
// 查询所有用户
public List<User> getAllUsers() {
List<User> users = new ArrayList<>();
String sql = "SELECT * FROM users ORDER BY id";
try (Connection conn = DatabaseUtil.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
User user = new User(
rs.getInt("id"),
rs.getString("name"),
rs.getString("email"),
rs.getInt("age")
);
users.add(user);
}
} catch (SQLException e) {
System.err.println("查询所有用户失败: " + e.getMessage());
}
return users;
}
// 更新用户
public boolean updateUser(User user) {
String sql = "UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getEmail());
pstmt.setInt(3, user.getAge());
pstmt.setInt(4, user.getId());
int rowsAffected = pstmt.executeUpdate();
System.out.println("更新用户成功,影响行数: " + rowsAffected);
return rowsAffected > 0;
} catch (SQLException e) {
System.err.println("更新用户失败: " + e.getMessage());
return false;
}
}
// 删除用户
public boolean deleteUser(int id) {
String sql = "DELETE FROM users WHERE id = ?";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
int rowsAffected = pstmt.executeUpdate();
System.out.println("删除用户成功,影响行数: " + rowsAffected);
return rowsAffected > 0;
} catch (SQLException e) {
System.err.println("删除用户失败: " + e.getMessage());
return false;
}
}
// 根据姓名模糊查询
public List<User> searchUsersByName(String namePattern) {
List<User> users = new ArrayList<>();
String sql = "SELECT * FROM users WHERE name LIKE ? ORDER BY id";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, "%" + namePattern + "%");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
User user = new User(
rs.getInt("id"),
rs.getString("name"),
rs.getString("email"),
rs.getInt("age")
);
users.add(user);
}
} catch (SQLException e) {
System.err.println("搜索用户失败: " + e.getMessage());
}
return users;
}
}
// 测试类
public class JDBCTest {
public static void main(String[] args) {
UserDAO userDAO = new UserDAO();
// 创建表
userDAO.createTable();
// 插入测试数据
User user1 = new User("张三", "zhangsan@example.com", 25);
User user2 = new User("李四", "lisi@example.com", 30);
User user3 = new User("王五", "wangwu@example.com", 28);
userDAO.insertUser(user1);
userDAO.insertUser(user2);
userDAO.insertUser(user3);
// 查询所有用户
System.out.println("\n=== 所有用户 ===");
List<User> allUsers = userDAO.getAllUsers();
allUsers.forEach(System.out::println);
// 根据ID查询
System.out.println("\n=== 查询ID为1的用户 ===");
User user = userDAO.getUserById(1);
System.out.println(user);
// 更新用户
if (user != null) {
user.setAge(26);
userDAO.updateUser(user);
System.out.println("\n=== 更新后的用户 ===");
User updatedUser = userDAO.getUserById(1);
System.out.println(updatedUser);
}
// 模糊查询
System.out.println("\n=== 搜索姓名包含'张'的用户 ===");
List<User> searchResults = userDAO.searchUsersByName("张");
searchResults.forEach(System.out::println);
// 删除用户
// userDAO.deleteUser(2);
// System.out.println("\n=== 删除ID为2的用户后 ===");
// userDAO.getAllUsers().forEach(System.out::println);
}
}
7.2 数据库连接池
java
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.SQLException;
// HikariCP 连接池配置
class ConnectionPoolConfig {
private static HikariDataSource dataSource;
static {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC");
config.setUsername("root");
config.setPassword("password");
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
// 连接池配置
config.setMaximumPoolSize(20); // 最大连接数
config.setMinimumIdle(5); // 最小空闲连接数
config.setConnectionTimeout(30000); // 连接超时时间(毫秒)
config.setIdleTimeout(600000); // 空闲超时时间(毫秒)
config.setMaxLifetime(1800000); // 连接最大生存时间(毫秒)
config.setLeakDetectionThreshold(60000); // 连接泄漏检测阈值
dataSource = new HikariDataSource(config);
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void closeDataSource() {
if (dataSource != null) {
dataSource.close();
}
}
}
// 使用连接池的DAO示例
class PooledUserDAO extends UserDAO {
@Override
public boolean insertUser(User user) {
String sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
try (Connection conn = ConnectionPoolConfig.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getEmail());
pstmt.setInt(3, user.getAge());
int rowsAffected = pstmt.executeUpdate();
System.out.println("使用连接池插入用户成功,影响行数: " + rowsAffected);
return rowsAffected > 0;
} catch (SQLException e) {
System.err.println("使用连接池插入用户失败: " + e.getMessage());
return false;
}
}
// 其他方法类似,只是使用连接池获取连接
}
8. Spring 框架
8.1 Spring Core (IoC/DI)
java
// 1. 配置类方式
import org.springframework.context.annotation.*;
import org.springframework.stereotype.*;
// 实体类
class User {
private Long id;
private String name;
private String email;
// 构造方法
public User() {}
public User(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// Getter和Setter
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "', email='" + email + "'}";
}
}
// 服务接口
interface UserService {
User findById(Long id);
void save(User user);
List<User> findAll();
}
// 服务实现类
@Service
class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public User findById(Long id) {
return userRepository.findById(id);
}
@Override
public void save(User user) {
userRepository.save(user);
}
@Override
public List<User> findAll() {
return userRepository.findAll();
}
}
// 仓库接口
interface UserRepository {
User findById(Long id);
void save(User user);
List<User> findAll();
}
// 仓库实现类
@Repository
class UserRepositoryImpl implements UserRepository {
// 模拟数据库存储
private static final Map<Long, User> userMap = new HashMap<>();
private static Long idCounter = 1L;
@Override
public User findById(Long id) {
return userMap.get(id);
}
@Override
public void save(User user) {
if (user.getId() == null) {
user.setId(idCounter++);
}
userMap.put(user.getId(), user);
System.out.println("保存用户: " + user);
}
@Override
public List<User> findAll() {
return new ArrayList<>(userMap.values());
}
}
// 配置类
@Configuration
@ComponentScan(basePackages = "com.example")
class AppConfig {
// 可以在这里定义Bean
@Bean
public User defaultUser() {
return new User(0L, "默认用户", "default@example.com");
}
}
// 控制器类
@Controller
class UserController {
@Autowired
private UserService userService;
public void createUser(String name, String email) {
User user = new User(null, name, email);
userService.save(user);
System.out.println("创建用户成功: " + user);
}
public User getUser(Long id) {
return userService.findById(id);
}
public List<User> getAllUsers() {
return userService.findAll();
}
}
// 主程序类
public class SpringCoreExample {
public static void main(String[] args) {
// 创建Spring应用上下文
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
// 获取Bean
UserController userController = context.getBean(UserController.class);
// 测试功能
userController.createUser("张三", "zhangsan@example.com");
userController.createUser("李四", "lisi@example.com");
System.out.println("\n=== 所有用户 ===");
userController.getAllUsers().forEach(System.out::println);
// 关闭上下文
context.close();
}
}
8.2 Spring Boot 基础
java
// pom.xml 依赖示例
/*
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
*/
// 主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
// 实体类
import javax.persistence.*;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(unique = true, nullable = false)
private String email;
private Integer age;
// 构造方法
public User() {}
public User(String name, String email, Integer age) {
this.name = name;
this.email = email;
this.age = age;
}
// Getter和Setter
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "', email='" + email + "', age=" + age + "}";
}
}
// Repository接口
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface UserRepository extends JpaRepository<User, Long> {
// 根据邮箱查找用户
User findByEmail(String email);
// 根据姓名查找用户(模糊查询)
List<User> findByNameContaining(String name);
// 自定义查询
@Query("SELECT u FROM User u WHERE u.age > :age")
List<User> findUsersOlderThan(@Param("age") Integer age);
}
// Service层
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> findAll() {
return userRepository.findAll();
}
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
public User save(User user) {
return userRepository.save(user);
}
public void deleteById(Long id) {
userRepository.deleteById(id);
}
public User findByEmail(String email) {
return userRepository.findByEmail(email);
}
public List<User> findByNameContaining(String name) {
return userRepository.findByNameContaining(name);
}
public List<User> findUsersOlderThan(Integer age) {
return userRepository.findUsersOlderThan(age);
}
}
// REST控制器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
// 获取所有用户
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
// 根据ID获取用户
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
Optional<User> user = userService.findById(id);
return user.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// 创建用户
@PostMapping
public User createUser(@RequestBody User user) {
return userService.save(user);
}
// 更新用户
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
Optional<User> optionalUser = userService.findById(id);
if (optionalUser.isPresent()) {
User user = optionalUser.get();
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
user.setAge(userDetails.getAge());
User updatedUser = userService.save(user);
return ResponseEntity.ok(updatedUser);
} else {
return ResponseEntity.notFound().build();
}
}
// 删除用户
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return ResponseEntity.ok().build();
}
// 根据邮箱查找用户
@GetMapping("/email/{email}")
public ResponseEntity<User> getUserByEmail(@PathVariable String email) {
User user = userService.findByEmail(email);
return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();
}
// 根据姓名模糊查询
@GetMapping("/search")
public List<User> searchUsers(@RequestParam String name) {
return userService.findByNameContaining(name);
}
// 查找年龄大于指定值的用户
@GetMapping("/older-than/{age}")
public List<User> getUsersOlderThan(@PathVariable Integer age) {
return userService.findUsersOlderThan(age);
}
}
// 配置文件 application.yml
/*
spring:
datasource:
url: jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
server:
port: 8080
*/
9. Web 开发
9.1 Servlet 基础
java
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
// 简单的用户实体类
class SimpleUser {
private int id;
private String name;
private String email;
public SimpleUser(int id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// Getter方法
public int getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
@Override
public String toString() {
return "SimpleUser{id=" + id + ", name='" + name + "', email='" + email + "'}";
}
}
// 模拟数据访问
class UserService {
private static List<SimpleUser> users = new ArrayList<>();
private static int nextId = 1;
static {
users.add(new SimpleUser(nextId++, "张三", "zhangsan@example.com"));
users.add(new SimpleUser(nextId++, "李四", "lisi@example.com"));
users.add(new SimpleUser(nextId++, "王五", "wangwu@example.com"));
}
public List<SimpleUser> getAllUsers() {
return new ArrayList<>(users);
}
public SimpleUser getUserById(int id) {
return users.stream()
.filter(user -> user.getId() == id)
.findFirst()
.orElse(null);
}
public void addUser(SimpleUser user) {
user = new SimpleUser(nextId++, user.getName(), user.getEmail());
users.add(user);
}
public boolean deleteUser(int id) {
return users.removeIf(user -> user.getId() == id);
}
}
// 用户列表Servlet
@WebServlet("/users")
public class UserListServlet extends HttpServlet {
private UserService userService = new UserService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
List<SimpleUser> users = userService.getAllUsers();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset='UTF-8'>");
out.println("<title>用户列表</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>用户列表</h1>");
out.println("<a href='add-user.html'>添加用户</a>");
out.println("<table border='1'>");
out.println("<tr><th>ID</th><th>姓名</th><th>邮箱</th><th>操作</th></tr>");
for (SimpleUser user : users) {
out.println("<tr>");
out.println("<td>" + user.getId() + "</td>");
out.println("<td>" + user.getName() + "</td>");
out.println("<td>" + user.getEmail() + "</td>");
out.println("<td><a href='delete-user?id=" + user.getId() + "'>删除</a></td>");
out.println("</tr>");
}
out.println("</table>");
out.println("</body>");
out.println("</html>");
}
}
// 添加用户Servlet
@WebServlet("/add-user")
public class AddUserServlet extends HttpServlet {
private UserService userService = new UserService();
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
String email = request.getParameter("email");
if (name != null && !name.trim().isEmpty() &&
email != null && !email.trim().isEmpty()) {
SimpleUser user = new SimpleUser(0, name, email);
userService.addUser(user);
}
// 重定向到用户列表
response.sendRedirect("users");
}
}
// 删除用户Servlet
@WebServlet("/delete-user")
public class DeleteUserServlet extends HttpServlet {
private UserService userService = new UserService();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String idParam = request.getParameter("id");
if (idParam != null && !idParam.trim().isEmpty()) {
try {
int id = Integer.parseInt(idParam);
userService.deleteUser(id);
} catch (NumberFormatException e) {
// 处理无效ID
}
}
// 重定向到用户列表
response.sendRedirect("users");
}
}
// JSON API Servlet
@WebServlet("/api/users")
public class UserApiServlet extends HttpServlet {
private UserService userService = new UserService();
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json;charset=UTF-8");
List<SimpleUser> users = userService.getAllUsers();
String json = objectMapper.writeValueAsString(users);
response.getWriter().write(json);
}
}
// web.xml 配置示例
/*
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>User Management Web App</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
*/
9.2 Spring MVC
java
// 控制器
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.validation.Valid;
import java.util.List;
@Controller
@RequestMapping("/users")
public class UserWebController {
@Autowired
private UserService userService;
// 显示用户列表页面
@GetMapping
public String listUsers(Model model) {
List<User> users = userService.findAll();
model.addAttribute("users", users);
return "user/list"; // 返回视图名称
}
// 显示添加用户表单
@GetMapping("/new")
public String showCreateForm(Model model) {
model.addAttribute("user", new User());
return "user/form";
}
// 处理添加用户请求
@PostMapping
public String createUser(@Valid @ModelAttribute User user,
BindingResult result,
RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
return "user/form";
}
try {
userService.save(user);
redirectAttributes.addFlashAttribute("message", "用户创建成功!");
return "redirect:/users";
} catch (Exception e) {
redirectAttributes.addFlashAttribute("error", "创建用户失败:" + e.getMessage());
return "redirect:/users/new";
}
}
// 显示编辑用户表单
@GetMapping("/edit/{id}")
public String showEditForm(@PathVariable Long id, Model model) {
User user = userService.findById(id).orElse(null);
if (user == null) {
return "redirect:/users";
}
model.addAttribute("user", user);
return "user/form";
}
// 处理更新用户请求
@PostMapping("/update/{id}")
public String updateUser(@PathVariable Long id,
@Valid @ModelAttribute User userDetails,
BindingResult result,
RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
return "user/form";
}
User user = userService.findById(id).orElse(null);
if (user == null) {
redirectAttributes.addFlashAttribute("error", "用户不存在");
return "redirect:/users";
}
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
user.setAge(userDetails.getAge());
userService.save(user);
redirectAttributes.addFlashAttribute("message", "用户更新成功!");
return "redirect:/users";
}
// 删除用户
@PostMapping("/delete/{id}")
public String deleteUser(@PathVariable Long id, RedirectAttributes redirectAttributes) {
userService.deleteById(id);
redirectAttributes.addFlashAttribute("message", "用户删除成功!");
return "redirect:/users";
}
}
// REST控制器
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@Autowired
private UserService userService;
// 获取所有用户
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.findAll();
return ResponseEntity.ok(users);
}
// 根据ID获取用户
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// 创建用户
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
// 更新用户
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id,
@Valid @RequestBody User userDetails) {
return userService.findById(id)
.map(user -> {
user.setName(userDetails.getName());
user.setEmail(userDetails.getEmail());
user.setAge(userDetails.getAge());
User updatedUser = userService.save(user);
return ResponseEntity.ok(updatedUser);
})
.orElse(ResponseEntity.notFound().build());
}
// 删除用户
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
return userService.findById(id)
.map(user -> {
userService.deleteById(id);
return ResponseEntity.ok().<Void>build();
})
.orElse(ResponseEntity.notFound().build());
}
}
// 全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFound(UserNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGeneralException(Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("服务器内部错误:" + e.getMessage());
}
}
// 自定义异常
public class UserNotFoundException extends RuntimeException {
public UserNotFoundException(String message) {
super(message);
}
}
10. 项目实践
10.1 完整的用户管理系统
java
// 项目结构说明
/*
src/
├── main/
│ ├── java/
│ │ └── com/example/usermanagement/
│ │ ├── UserManagementApplication.java // 启动类
│ │ ├── controller/ // 控制器层
│ │ │ ├── UserController.java
│ │ │ └── UserWebController.java
│ │ ├── service/ // 服务层
│ │ │ ├── UserService.java
│ │ │ └── impl/UserServiceImpl.java
│ │ ├── repository/ // 数据访问层
│ │ │ └── UserRepository.java
│ │ ├── entity/ // 实体类
│ │ │ └── User.java
│ │ ├── dto/ // 数据传输对象
│ │ │ ├── UserDTO.java
│ │ │ └── UserCreateRequest.java
│ │ └── exception/ // 异常处理
│ │ ├── GlobalExceptionHandler.java
│ │ └── UserNotFoundException.java
│ ├── resources/
│ │ ├── application.yml // 配置文件
│ │ ├── static/ // 静态资源
│ │ └── templates/ // 模板文件
│ └── webapp/ // Web资源
└── test/
└── java/
└── com/example/usermanagement/
*/
// 启动类
@SpringBootApplication
public class UserManagementApplication {
public static void main(String[] args) {
SpringApplication.run(UserManagementApplication.class, args);
}
}
// DTO - 用户创建请求
public class UserCreateRequest {
@NotBlank(message = "姓名不能为空")
@Size(min = 2, max = 50, message = "姓名长度必须在2-50个字符之间")
private String name;
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 150, message = "年龄不能大于150")
private Integer age;
// Getter和Setter
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
}
// DTO - 用户响应
public class UserResponse {
private Long id;
private String name;
private String email;
private Integer age;
private LocalDateTime createdAt;
// 构造方法
public UserResponse(User user) {
this.id = user.getId();
this.name = user.getName();
this.email = user.getEmail();
this.age = user.getAge();
this.createdAt = user.getCreatedAt();
}
// Getter方法
public Long getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
public Integer getAge() { return age; }
public LocalDateTime getCreatedAt() { return createdAt; }
}
// 服务接口
public interface UserService {
List<UserResponse> findAll();
Optional<UserResponse> findById(Long id);
UserResponse save(UserCreateRequest request);
UserResponse update(Long id, UserCreateRequest request);
void deleteById(Long id);
Optional<User> findByEmail(String email);
}
// 服务实现
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional(readOnly = true)
public List<UserResponse> findAll() {
return userRepository.findAll()
.stream()
.map(UserResponse::new)
.collect(Collectors.toList());
}
@Override
@Transactional(readOnly = true)
public Optional<UserResponse> findById(Long id) {
return userRepository.findById(id)
.map(UserResponse::new);
}
@Override
public UserResponse save(UserCreateRequest request) {
// 检查邮箱是否已存在
if (userRepository.existsByEmail(request.getEmail())) {
throw new IllegalArgumentException("邮箱已存在:" + request.getEmail());
}
User user = new User();
user.setName(request.getName());
user.setEmail(request.getEmail());
user.setAge(request.getAge());
user.setCreatedAt(LocalDateTime.now());
User savedUser = userRepository.save(user);
return new UserResponse(savedUser);
}
@Override
public UserResponse update(Long id, UserCreateRequest request) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException("用户不存在,ID:" + id));
// 检查邮箱是否被其他用户使用
User existingUser = userRepository.findByEmail(request.getEmail());
if (existingUser != null && !existingUser.getId().equals(id)) {
throw new IllegalArgumentException("邮箱已被其他用户使用:" + request.getEmail());
}
user.setName(request.getName());
user.setEmail(request.getEmail());
user.setAge(request.getAge());
User updatedUser = userRepository.save(user);
return new UserResponse(updatedUser);
}
@Override
public void deleteById(Long id) {
if (!userRepository.existsById(id)) {
throw new UserNotFoundException("用户不存在,ID:" + id);
}
userRepository.deleteById(id);
}
@Override
@Transactional(readOnly = true)
public Optional<User> findByEmail(String email) {
return Optional.ofNullable(userRepository.findByEmail(email));
}
}
// REST控制器
@RestController
@RequestMapping("/api/v1/users")
@Validated
public class UserRestController {
@Autowired
private UserService userService;
@GetMapping
public ResponseEntity<List<UserResponse>> getAllUsers() {
List<UserResponse> users = userService.findAll();
return ResponseEntity.ok(users);
}
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUserById(@PathVariable Long id) {
return userService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
public ResponseEntity<UserResponse> createUser(@Valid @RequestBody UserCreateRequest request) {
try {
UserResponse user = userService.save(request);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().build();
}
}
@PutMapping("/{id}")
public ResponseEntity<UserResponse> updateUser(@PathVariable Long id,
@Valid @RequestBody UserCreateRequest request) {
try {
UserResponse user = userService.update(id, request);
return ResponseEntity.ok(user);
} catch (UserNotFoundException e) {
return ResponseEntity.notFound().build();
} catch (IllegalArgumentException e) {
return ResponseEntity.badRequest().build();
}
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
try {
userService.deleteById(id);
return ResponseEntity.noContent().build();
} catch (UserNotFoundException e) {
return ResponseEntity.notFound().build();
}
}
}
// Web控制器
@Controller
@RequestMapping("/web/users")
public class UserWebController {
@Autowired
private UserService userService;
@GetMapping
public String listUsers(Model model) {
List<UserResponse> users = userService.findAll();
model.addAttribute("users", users);
return "users/list";
}
@GetMapping("/new")
public String showCreateForm(Model model) {
model.addAttribute("userRequest", new UserCreateRequest());
return "users/form";
}
@PostMapping
public String createUser(@Valid @ModelAttribute("userRequest") UserCreateRequest request,
BindingResult result,
RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
return "users/form";
}
try {
userService.save(request);
redirectAttributes.addFlashAttribute("message", "用户创建成功!");
return "redirect:/web/users";
} catch (IllegalArgumentException e) {
result.rejectValue("email", "error.user", e.getMessage());
return "users/form";
}
}
@GetMapping("/edit/{id}")
public String showEditForm(@PathVariable Long id, Model model) {
return userService.findById(id)
.map(user -> {
UserCreateRequest request = new UserCreateRequest();
request.setName(user.getName());
request.setEmail(user.getEmail());
request.setAge(user.getAge());
model.addAttribute("userRequest", request);
model.addAttribute("userId", id);
return "users/form";
})
.orElse("redirect:/web/users");
}
@PostMapping("/update/{id}")
public String updateUser(@PathVariable Long id,
@Valid @ModelAttribute("userRequest") UserCreateRequest request,
BindingResult result,
RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
return "users/form";
}
try {
userService.update(id, request);
redirectAttributes.addFlashAttribute("message", "用户更新成功!");
return "redirect:/web/users";
} catch (UserNotFoundException e) {
redirectAttributes.addFlashAttribute("error", "用户不存在");
return "redirect:/web/users";
} catch (IllegalArgumentException e) {
result.rejectValue("email", "error.user", e.getMessage());
return "users/form";
}
}
@PostMapping("/delete/{id}")
public String deleteUser(@PathVariable Long id, RedirectAttributes redirectAttributes) {
try {
userService.deleteById(id);
redirectAttributes.addFlashAttribute("message", "用户删除成功!");
} catch (UserNotFoundException e) {
redirectAttributes.addFlashAttribute("error", "用户不存在");
}
return "redirect:/web/users";
}
}
// Thymeleaf 模板示例 (resources/templates/users/list.html)
/*
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>用户管理</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
<h1>用户列表</h1>
<div th:if="${message}" class="alert alert-success" th:text="${message}"></div>
<div th:if="${error}" class="alert alert-danger" th:text="${error}"></div>
<div class="mb-3">
<a href="/web/users/new" class="btn btn-primary">添加用户</a>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>邮箱</th>
<th>年龄</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.email}"></td>
<td th:text="${user.age}"></td>
<td th:text="${#temporals.format(user.createdAt, 'yyyy-MM-dd HH:mm:ss')}"></td>
<td>
<a th:href="@{/web/users/edit/{id}(id=${user.id})}" class="btn btn-sm btn-warning">编辑</a>
<form th:action="@{/web/users/delete/{id}(id=${user.id})}" method="post" style="display:inline;">
<button type="submit" class="btn btn-sm btn-danger"
onclick="return confirm('确定要删除这个用户吗?')">删除</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
*/
10.2 测试
java
// 单元测试
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
@SpringBootTest
class UserServiceTest {
@Test
void testCreateUser() {
// 准备测试数据
UserCreateRequest request = new UserCreateRequest();
request.setName("测试用户");
request.setEmail("test@example.com");
request.setAge(25);
// 执行测试
UserResponse response = userService.save(request);
// 验证结果
assertNotNull(response.getId());
assertEquals("测试用户", response.getName());
assertEquals("test@example.com", response.getEmail());
assertEquals(25, response.getAge());
}
@Test
void testFindUserById() {
// 准备测试数据
UserCreateRequest request = new UserCreateRequest();
request.setName("测试用户");
request.setEmail("test@example.com");
request.setAge(25);
UserResponse createdUser = userService.save(request);
// 执行测试
Optional<UserResponse> foundUser = userService.findById(createdUser.getId());
// 验证结果
assertTrue(foundUser.isPresent());
assertEquals(createdUser.getId(), foundUser.get().getId());
}
}
// 集成测试
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest
@AutoConfigureWebMvc
class UserRestControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void testGetAllUsers() throws Exception {
mockMvc.perform(get("/api/v1/users")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$").isArray());
}
@Test
void testCreateUser() throws Exception {
String userJson = """
{
"name": "测试用户",
"email": "test@example.com",
"age": 25
}
""";
mockMvc.perform(post("/api/v1/users")
.contentType(MediaType.APPLICATION_JSON)
.content(userJson))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.name").value("测试用户"))
.andExpect(jsonPath("$.email").value("test@example.com"));
}
}
11. 总结
这份复习指南涵盖了 Java 后端开发的核心知识点:
11.1 基础部分(详细)
- Java 语法基础
- 面向对象编程
- 集合框架
- 异常处理
11.2 进阶部分(中等详细)
- 多线程编程
- IO/NIO 操作
- 数据库操作(JDBC)
- Spring 框架基础
11.3 高级部分(概要)
- Web 开发(Servlet/Spring MVC)
- 项目实践和测试
11.4 学习建议
- 循序渐进:从基础语法开始,逐步深入
- 动手实践:每个知识点都要写代码验证
- 项目驱动:通过完整项目整合所学知识
- 持续学习:关注新技术发展,如 Spring Boot、微服务等