引言

Java作为一门历史悠久且应用广泛的编程语言,其生态系统庞大且复杂。从基础语法到高级框架,从单机应用到分布式系统,Java的学习路径漫长而富有挑战。本指南旨在为学习者提供一个从基础到精通的系统化学习路线,涵盖核心概念、高级特性以及实战技巧,帮助你构建扎实的知识体系并提升实际开发能力。

第一部分:Java基础巩固与深化

1.1 面向对象编程(OOP)核心

Java是一门纯粹的面向对象语言,深入理解OOP是掌握Java的基石。

核心概念:

  • 封装:将数据(属性)和操作数据的方法(行为)捆绑在一起,并隐藏内部实现细节。
  • 继承:允许子类继承父类的属性和方法,实现代码复用。
  • 多态:同一接口可以有多种不同的实现方式,提高了代码的灵活性和可扩展性。

实战示例:

// 封装示例
class BankAccount {
    private double balance; // 私有属性,隐藏内部状态

    public BankAccount(double initialBalance) {
        if (initialBalance >= 0) {
            this.balance = initialBalance;
        }
    }

    // 公共方法提供受控访问
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("存款成功,当前余额:" + balance);
        }
    }

    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("取款成功,当前余额:" + balance);
        } else {
            System.out.println("取款失败,余额不足或金额无效");
        }
    }

    public double getBalance() {
        return balance;
    }
}

// 继承与多态示例
abstract class Shape {
    abstract double area(); // 抽象方法,强制子类实现
}

class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double area() {
        return width * height;
    }
}

// 使用多态
public class OOPDemo {
    public static void main(String[] args) {
        Shape circle = new Circle(5.0);
        Shape rectangle = new Rectangle(4.0, 6.0);
        
        System.out.println("圆形面积: " + circle.area());
        System.out.println("矩形面积: " + rectangle.area());
    }
}

1.2 集合框架(Collections Framework)

Java集合框架是处理数据集合的核心,包括List、Set、Map等接口及其实现类。

核心接口与实现类:

  • List:有序可重复集合,常用实现类:ArrayList、LinkedList
  • Set:无序不可重复集合,常用实现类:HashSet、TreeSet
  • Map:键值对映射,常用实现类:HashMap、TreeMap

实战示例:

import java.util.*;

public class CollectionsDemo {
    public static void main(String[] args) {
        // List使用示例
        List<String> fruits = new ArrayList<>();
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Apple"); // 允许重复
        
        System.out.println("水果列表: " + fruits);
        System.out.println("第二个元素: " + fruits.get(1));
        
        // Set使用示例
        Set<String> uniqueFruits = new HashSet<>();
        uniqueFruits.add("Apple");
        uniqueFruits.add("Banana");
        uniqueFruits.add("Apple"); // 重复元素不会被添加
        
        System.out.println("唯一水果集合: " + uniqueFruits);
        
        // Map使用示例
        Map<String, Integer> fruitPrices = new HashMap<>();
        fruitPrices.put("Apple", 5);
        fruitPrices.put("Banana", 3);
        fruitPrices.put("Orange", 4);
        
        System.out.println("苹果价格: " + fruitPrices.get("Apple"));
        
        // 遍历Map
        for (Map.Entry<String, Integer> entry : fruitPrices.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}

1.3 异常处理机制

Java的异常处理机制是健壮程序的基础,理解checked和unchecked异常的区别至关重要。

异常分类:

  • Checked Exception:编译时异常,必须处理(如IOException)
  • Unchecked Exception:运行时异常,可选处理(如NullPointerException)

实战示例:

import java.io.*;

public class ExceptionDemo {
    // 自定义异常
    static class InsufficientFundsException extends Exception {
        public InsufficientFundsException(String message) {
            super(message);
        }
    }

    static class BankAccount {
        private double balance;

        public BankAccount(double balance) {
            this.balance = balance;
        }

        public void withdraw(double amount) throws InsufficientFundsException {
            if (amount > balance) {
                throw new InsufficientFundsException("余额不足,当前余额: " + balance);
            }
            balance -= amount;
        }
    }

    public static void main(String[] args) {
        BankAccount account = new BankAccount(100);
        
        try {
            account.withdraw(150);
        } catch (InsufficientFundsException e) {
            System.err.println("取款失败: " + e.getMessage());
        } finally {
            System.out.println("操作完成");
        }
        
        // 处理IOException
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            System.err.println("文件读取错误: " + e.getMessage());
        }
    }
}

第二部分:Java高级特性

2.1 泛型(Generics)

泛型提供了编译时类型安全检查,避免了运行时的ClassCastException。

核心概念:

  • 类型参数化:在类、接口、方法中使用类型参数
  • 类型擦除:编译时泛型信息被擦除,转换为Object或边界类型
  • 通配符:? 表示未知类型,? extends T 上界通配符,? super T 下界通配符

实战示例:

import java.util.*;

// 泛型类
class Box<T> {
    private T content;

    public Box(T content) {
        this.content = content;
    }

    public T getContent() {
        return content;
    }

    public void setContent(T content) {
        this.content = content;
    }
}

// 泛型方法
class GenericMethods {
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }

    public static <T extends Number> double sum(T[] array) {
        double sum = 0;
        for (T element : array) {
            sum += element.doubleValue();
        }
        return sum;
    }
}

// 通配符使用
class WildcardDemo {
    public static void printList(List<?> list) {
        for (Object elem : list) {
            System.out.print(elem + " ");
        }
        System.out.println();
    }

    public static void addNumbers(List<? super Integer> list) {
        list.add(1);
        list.add(2);
    }

    public static void processNumbers(List<? extends Number> list) {
        for (Number num : list) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

public class GenericsDemo {
    public static void main(String[] args) {
        // 泛型类使用
        Box<String> stringBox = new Box<>("Hello");
        Box<Integer> intBox = new Box<>(123);
        
        System.out.println("字符串盒子: " + stringBox.getContent());
        System.out.println("整数盒子: " + intBox.getContent());
        
        // 泛型方法使用
        String[] strArray = {"A", "B", "C"};
        Integer[] intArray = {1, 2, 3, 4, 5};
        
        GenericMethods.printArray(strArray);
        GenericMethods.printArray(intArray);
        
        System.out.println("整数数组求和: " + GenericMethods.sum(intArray));
        
        // 通配符使用
        List<String> stringList = new ArrayList<>();
        stringList.add("Java");
        stringList.add("Python");
        
        List<Integer> intList = new ArrayList<>();
        intList.add(10);
        intList.add(20);
        
        WildcardDemo.printList(stringList);
        WildcardDemo.printList(intList);
        
        List<Object> objectList = new ArrayList<>();
        WildcardDemo.addNumbers(objectList);
        System.out.println("添加数字后的对象列表: " + objectList);
        
        WildcardDemo.processNumbers(intList);
    }
}

2.2 反射(Reflection)

反射机制允许程序在运行时动态获取类的信息并操作类的成员。

核心API:

  • Class 类:获取类的元数据
  • Constructor:获取构造方法
  • Field:获取和操作字段
  • Method:获取和调用方法

实战示例:

import java.lang.reflect.*;

public class ReflectionDemo {
    // 定义一个用于反射的类
    static class Person {
        private String name;
        private int age;

        public Person() {
            this.name = "Unknown";
            this.age = 0;
        }

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void sayHello() {
            System.out.println("Hello, I'm " + name);
        }

        private void privateMethod() {
            System.out.println("这是一个私有方法");
        }
    }

    public static void main(String[] args) throws Exception {
        // 获取Class对象
        Class<?> personClass = Person.class;
        
        // 获取构造方法
        Constructor<?>[] constructors = personClass.getConstructors();
        System.out.println("公共构造方法:");
        for (Constructor<?> constructor : constructors) {
            System.out.println("  " + constructor);
        }
        
        // 使用反射创建对象
        Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
        Person person = (Person) constructor.newInstance("Alice", 25);
        System.out.println("创建的对象: " + person.getName());
        
        // 获取字段
        Field[] fields = personClass.getDeclaredFields();
        System.out.println("所有字段:");
        for (Field field : fields) {
            System.out.println("  " + field.getName() + " (" + field.getType() + ")");
        }
        
        // 访问私有字段
        Field nameField = personClass.getDeclaredField("name");
        nameField.setAccessible(true); // 允许访问私有字段
        nameField.set(person, "Bob");
        System.out.println("修改后的名字: " + person.getName());
        
        // 获取方法
        Method[] methods = personClass.getDeclaredMethods();
        System.out.println("所有方法:");
        for (Method method : methods) {
            System.out.println("  " + method.getName());
        }
        
        // 调用方法
        Method sayHelloMethod = personClass.getMethod("sayHello");
        sayHelloMethod.invoke(person);
        
        // 调用私有方法
        Method privateMethod = personClass.getDeclaredMethod("privateMethod");
        privateMethod.setAccessible(true);
        privateMethod.invoke(person);
    }
}

2.3 注解(Annotations)

注解是Java 5引入的元数据机制,用于提供额外的信息给编译器、工具或运行时。

常用内置注解:

  • @Override:标记方法重写
  • @Deprecated:标记已过时的方法/类
  • @SuppressWarnings:抑制编译警告
  • @FunctionalInterface:标记函数式接口

自定义注解示例:

import java.lang.annotation.*;
import java.lang.reflect.Method;

// 定义自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyAnnotation {
    String value() default "default";
    int priority() default 1;
}

// 使用注解的类
class AnnotatedClass {
    @MyAnnotation(value = "测试方法", priority = 2)
    public void annotatedMethod() {
        System.out.println("执行带注解的方法");
    }

    @MyAnnotation("另一个方法")
    public void anotherMethod() {
        System.out.println("执行另一个带注解的方法");
    }

    public void normalMethod() {
        System.out.println("普通方法");
    }
}

public class AnnotationDemo {
    public static void main(String[] args) throws Exception {
        AnnotatedClass obj = new AnnotatedClass();
        Class<?> clazz = obj.getClass();
        
        // 获取所有方法
        Method[] methods = clazz.getDeclaredMethods();
        
        for (Method method : methods) {
            // 检查方法是否有MyAnnotation注解
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                System.out.println("方法: " + method.getName());
                System.out.println("  注解值: " + annotation.value());
                System.out.println("  优先级: " + annotation.priority());
                
                // 调用带注解的方法
                method.invoke(obj);
                System.out.println();
            }
        }
    }
}

第三部分:Java并发编程

3.1 线程基础与创建方式

Java提供了多种创建线程的方式,理解每种方式的适用场景很重要。

创建线程的三种方式:

  1. 继承Thread
  2. 实现Runnable接口
  3. 实现Callable接口(带返回值)

实战示例:

import java.util.concurrent.*;

// 方式1:继承Thread类
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程 " + Thread.currentThread().getId() + " 正在运行");
    }
}

// 方式2:实现Runnable接口
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable线程 " + Thread.currentThread().getId() + " 正在运行");
    }
}

// 方式3:实现Callable接口(带返回值)
class MyCallable implements Callable<String> {
    private int taskNumber;
    
    public MyCallable(int taskNumber) {
        this.taskNumber = taskNumber;
    }
    
    @Override
    public String call() throws Exception {
        System.out.println("任务 " + taskNumber + " 开始执行");
        Thread.sleep(1000);
        return "任务 " + taskNumber + " 完成,结果: " + (taskNumber * 2);
    }
}

public class ThreadCreationDemo {
    public static void main(String[] args) throws Exception {
        // 方式1:继承Thread
        MyThread thread1 = new MyThread();
        thread1.start();
        
        // 方式2:实现Runnable
        Thread thread2 = new Thread(new MyRunnable());
        thread2.start();
        
        // 方式3:实现Callable
        ExecutorService executor = Executors.newFixedThreadPool(3);
        Future<String> future = executor.submit(new MyCallable(1));
        
        // 获取结果(会阻塞直到任务完成)
        String result = future.get();
        System.out.println("Callable结果: " + result);
        
        // 关闭线程池
        executor.shutdown();
    }
}

3.2 线程同步与锁机制

多线程环境下,共享资源的访问需要同步机制来保证数据一致性。

核心概念:

  • synchronized:内置锁,可修饰方法或代码块
  • Lock接口:更灵活的锁机制,如ReentrantLock
  • volatile:保证变量的可见性
  • 原子类:AtomicInteger等,提供原子操作

实战示例:

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

public class SynchronizationDemo {
    // 使用synchronized的计数器
    static class SynchronizedCounter {
        private int count = 0;

        public synchronized void increment() {
            count++;
        }

        public synchronized int getCount() {
            return count;
        }
    }

    // 使用ReentrantLock的计数器
    static class LockCounter {
        private int count = 0;
        private final ReentrantLock lock = new ReentrantLock();

        public void increment() {
            lock.lock();
            try {
                count++;
            } finally {
                lock.unlock();
            }
        }

        public int getCount() {
            lock.lock();
            try {
                return count;
            } finally {
                lock.unlock();
            }
        }
    }

    // 使用原子类的计数器
    static class AtomicCounter {
        private AtomicInteger count = new AtomicInteger(0);

        public void increment() {
            count.incrementAndGet();
        }

        public int getCount() {
            return count.get();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // 测试synchronized计数器
        SynchronizedCounter syncCounter = new SynchronizedCounter();
        testCounter(syncCounter, "synchronized");
        
        // 测试Lock计数器
        LockCounter lockCounter = new LockCounter();
        testCounter(lockCounter, "ReentrantLock");
        
        // 测试原子计数器
        AtomicCounter atomicCounter = new AtomicCounter();
        testCounter(atomicCounter, "AtomicInteger");
    }

    static void testCounter(Object counter, String type) throws InterruptedException {
        final int threadCount = 10;
        final int incrementsPerThread = 1000;
        
        Thread[] threads = new Thread[threadCount];
        
        for (int i = 0; i < threadCount; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < incrementsPerThread; j++) {
                    if (counter instanceof SynchronizedCounter) {
                        ((SynchronizedCounter) counter).increment();
                    } else if (counter instanceof LockCounter) {
                        ((LockCounter) counter).increment();
                    } else if (counter instanceof AtomicCounter) {
                        ((AtomicCounter) counter).increment();
                    }
                }
            });
            threads[i].start();
        }
        
        for (Thread thread : threads) {
            thread.join();
        }
        
        int finalCount = 0;
        if (counter instanceof SynchronizedCounter) {
            finalCount = ((SynchronizedCounter) counter).getCount();
        } else if (counter instanceof LockCounter) {
            finalCount = ((LockCounter) counter).getCount();
        } else if (counter instanceof AtomicCounter) {
            finalCount = ((AtomicCounter) counter).getCount();
        }
        
        System.out.println(type + " 计数器最终值: " + finalCount + 
                          " (期望值: " + (threadCount * incrementsPerThread) + ")");
    }
}

3.3 并发工具类

Java并发包(java.util.concurrent)提供了丰富的并发工具类。

常用工具类:

  • ExecutorService:线程池管理
  • Future/Callable:异步任务和结果获取
  • CountDownLatch:等待多个线程完成
  • CyclicBarrier:线程间同步点
  • Semaphore:控制并发数量
  • ConcurrentHashMap:线程安全的Map

实战示例:

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ConcurrencyToolsDemo {
    public static void main(String[] args) throws Exception {
        // 1. 线程池使用
        ExecutorService executor = Executors.newFixedThreadPool(5);
        
        // 提交多个任务
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("任务 " + taskId + " 在线程 " + 
                                 Thread.currentThread().getName() + " 中执行");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        
        // 2. CountDownLatch示例
        CountDownLatch latch = new CountDownLatch(3);
        
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try {
                    System.out.println("线程 " + Thread.currentThread().getId() + " 准备就绪");
                    Thread.sleep(1000);
                    System.out.println("线程 " + Thread.currentThread().getId() + " 完成任务");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    latch.countDown();
                }
            }).start();
        }
        
        System.out.println("主线程等待所有子线程完成...");
        latch.await(); // 等待所有线程完成
        System.out.println("所有子线程已完成!");
        
        // 3. CyclicBarrier示例
        CyclicBarrier barrier = new CyclicBarrier(3, () -> {
            System.out.println("所有线程到达屏障点,继续执行");
        });
        
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try {
                    System.out.println("线程 " + Thread.currentThread().getId() + " 到达屏障");
                    barrier.await(); // 等待其他线程
                    System.out.println("线程 " + Thread.currentThread().getId() + " 继续执行");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
        
        // 4. Semaphore示例(控制并发数)
        Semaphore semaphore = new Semaphore(2); // 允许2个线程同时访问
        
        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    semaphore.acquire(); // 获取许可
                    System.out.println("线程 " + Thread.currentThread().getId() + " 获得许可,开始执行");
                    Thread.sleep(2000);
                    System.out.println("线程 " + Thread.currentThread().getId() + " 执行完成,释放许可");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    semaphore.release();
                }
            }).start();
        }
        
        // 5. ConcurrentHashMap示例
        ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
        
        // 多个线程同时操作
        ExecutorService mapExecutor = Executors.newFixedThreadPool(10);
        AtomicInteger counter = new AtomicInteger(0);
        
        for (int i = 0; i < 100; i++) {
            mapExecutor.submit(() -> {
                String key = "key-" + counter.incrementAndGet();
                concurrentMap.put(key, Thread.currentThread().getId());
            });
        }
        
        mapExecutor.shutdown();
        mapExecutor.awaitTermination(1, TimeUnit.SECONDS);
        
        System.out.println("ConcurrentHashMap大小: " + concurrentMap.size());
        
        // 关闭线程池
        executor.shutdown();
        executor.awaitTermination(10, TimeUnit.SECONDS);
    }
}

第四部分:JVM与性能优化

4.1 JVM内存模型

理解JVM内存结构是进行性能调优的基础。

JVM内存区域:

  • 堆(Heap):对象实例存储区域,分为新生代和老年代
  • 方法区(Method Area):存储类信息、常量、静态变量等(JDK 8后称为元空间)
  • 虚拟机栈(VM Stack):存储局部变量、方法调用等
  • 本地方法栈(Native Method Stack):为Native方法服务
  • 程序计数器(Program Counter Register):记录当前线程执行的字节码指令地址

实战示例:

// 演示JVM内存使用
public class JVMMemoryDemo {
    // 静态变量存储在方法区(元空间)
    private static String staticString = "静态字符串";
    
    // 实例变量存储在堆中
    private String instanceString = "实例字符串";
    
    // 局部变量存储在栈中
    public void method() {
        String localVar = "局部变量";
        System.out.println(localVar);
    }
    
    // 大对象演示(可能直接进入老年代)
    public void createLargeObject() {
        // 创建一个大数组,可能直接进入老年代
        byte[] largeArray = new byte[10 * 1024 * 1024]; // 10MB
        System.out.println("创建了10MB的大数组");
    }
    
    // 内存泄漏演示
    static class MemoryLeak {
        private static List<byte[]> leakList = new ArrayList<>();
        
        public static void addData() {
            // 每次调用添加1MB数据,但不释放,导致内存泄漏
            byte[] data = new byte[1024 * 1024];
            leakList.add(data);
            System.out.println("添加了1MB数据,当前列表大小: " + leakList.size() + "MB");
        }
    }
    
    public static void main(String[] args) {
        JVMMemoryDemo demo = new JVMMemoryDemo();
        demo.method();
        
        // 演示大对象
        demo.createLargeObject();
        
        // 演示内存泄漏(注意:实际运行时需要调整JVM参数)
        // MemoryLeak.addData();
        // MemoryLeak.addData();
    }
}

4.2 垃圾回收机制(GC)

Java的垃圾回收机制自动管理内存,但理解GC原理对性能调优至关重要。

GC核心概念:

  • 标记-清除:先标记存活对象,再清除未标记对象
  • 复制算法:将内存分为两块,每次只使用一块,复制存活对象到另一块
  • 标记-整理:标记存活对象,然后将存活对象向一端移动,清理另一端
  • 分代收集:新生代使用复制算法,老年代使用标记-整理算法

GC调优实战:

// JVM参数示例(在运行时添加)
// -Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=45

public class GCDemo {
    // 创建大量对象,触发GC
    public static void createObjects() {
        List<Object> list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            list.add(new byte[1024]); // 每个对象1KB
            if (i % 10000 == 0) {
                System.out.println("已创建 " + i + " 个对象");
            }
        }
        // 清空列表,使对象可被回收
        list.clear();
    }
    
    // 强引用、软引用、弱引用、虚引用示例
    public static void referenceDemo() {
        // 强引用
        Object strongRef = new Object();
        
        // 软引用(内存不足时回收)
        SoftReference<Object> softRef = new SoftReference<>(new Object());
        
        // 弱引用(下次GC时回收)
        WeakReference<Object> weakRef = new WeakReference<>(new Object());
        
        // 虚引用(用于对象回收跟踪)
        PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), null);
        
        System.out.println("强引用对象: " + strongRef);
        System.out.println("软引用对象: " + softRef.get());
        System.out.println("弱引用对象: " + weakRef.get());
        System.out.println("虚引用对象: " + phantomRef.get());
    }
    
    public static void main(String[] args) {
        // referenceDemo();
        
        // 创建对象触发GC
        for (int i = 0; i < 5; i++) {
            System.out.println("第 " + (i + 1) + " 轮创建对象");
            createObjects();
            System.gc(); // 建议JVM进行GC(不保证立即执行)
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

4.3 性能监控与调优工具

常用工具:

  • jvisualvm:JDK自带的可视化监控工具
  • jconsole:JDK自带的监控工具
  • jstat:监控JVM统计信息
  • jmap:生成堆转储文件
  • jstack:生成线程转储文件
  • Arthas:阿里开源的诊断工具

实战示例:

// 模拟性能问题代码
public class PerformanceDemo {
    // 模拟CPU密集型任务
    public static void cpuIntensiveTask() {
        long startTime = System.currentTimeMillis();
        long result = 0;
        for (long i = 0; i < 1000000000L; i++) {
            result += i;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("CPU密集型任务耗时: " + (endTime - startTime) + "ms, 结果: " + result);
    }
    
    // 模拟内存密集型任务
    public static void memoryIntensiveTask() {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            list.add(new byte[1024 * 1024]); // 每个1MB
        }
        System.out.println("内存密集型任务完成,分配了1GB内存");
    }
    
    // 模拟I/O密集型任务
    public static void ioIntensiveTask() throws Exception {
        File file = new File("test_large.txt");
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
            for (int i = 0; i < 1000000; i++) {
                writer.write("Line " + i + ": This is a test line for I/O operations.\n");
            }
        }
        System.out.println("I/O密集型任务完成");
    }
    
    public static void main(String[] args) throws Exception {
        // 运行不同类型的性能任务
        cpuIntensiveTask();
        memoryIntensiveTask();
        ioIntensiveTask();
        
        // 模拟线程死锁
        simulateDeadlock();
    }
    
    // 模拟死锁
    private static void simulateDeadlock() {
        Object lock1 = new Object();
        Object lock2 = new Object();
        
        Thread thread1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("线程1获取lock1");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("线程1获取lock2");
                }
            }
        });
        
        Thread thread2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("线程2获取lock2");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("线程2获取lock1");
                }
            }
        });
        
        thread1.start();
        thread2.start();
    }
}

第五部分:Java高级框架与生态

5.1 Spring框架核心

Spring是Java企业级开发的事实标准,掌握Spring是高级Java开发者的必备技能。

核心概念:

  • IoC(控制反转):将对象的创建和管理交给Spring容器
  • DI(依赖注入):通过构造器、setter或字段注入依赖
  • AOP(面向切面编程):在不修改源代码的情况下添加额外功能
  • Spring Boot:简化Spring应用的配置和部署

实战示例:

// Spring Boot应用示例
// 1. 主应用类
@SpringBootApplication
public class SpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplication.class, args);
    }
}

// 2. 实体类
@Entity
@Table(name = "users")
class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;
    private String email;
    
    // 构造函数、getter、setter省略
}

// 3. Repository接口
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
    List<User> findByName(String name);
}

// 4. Service层
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    public User createUser(User user) {
        return userRepository.save(user);
    }
    
    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
    
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

// 5. Controller层
@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @PostMapping
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.createUser(user);
        return ResponseEntity.ok(createdUser);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        if (user != null) {
            return ResponseEntity.ok(user);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    
    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        return ResponseEntity.ok(userService.getAllUsers());
    }
}

// 6. 配置类
@Configuration
public class AppConfig {
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

5.2 MyBatis与数据库操作

MyBatis是优秀的持久层框架,提供灵活的SQL映射。

核心概念:

  • SqlSessionFactory:创建SqlSession的工厂
  • SqlSession:执行SQL操作的核心接口
  • Mapper接口:定义数据库操作方法
  • XML映射文件:SQL语句和结果映射

实战示例:

<!-- UserMapper.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
    <!-- 结果映射 -->
    <resultMap id="UserResultMap" type="com.example.entity.User">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="email" column="email"/>
        <result property="createTime" column="create_time"/>
    </resultMap>
    
    <!-- 查询所有用户 -->
    <select id="selectAll" resultMap="UserResultMap">
        SELECT * FROM users
    </select>
    
    <!-- 根据ID查询用户 -->
    <select id="selectById" parameterType="Long" resultMap="UserResultMap">
        SELECT * FROM users WHERE id = #{id}
    </select>
    
    <!-- 根据邮箱查询用户 -->
    <select id="selectByEmail" parameterType="String" resultMap="UserResultMap">
        SELECT * FROM users WHERE email = #{email}
    </select>
    
    <!-- 插入用户 -->
    <insert id="insert" parameterType="com.example.entity.User">
        INSERT INTO users (name, email, create_time)
        VALUES (#{name}, #{email}, #{createTime})
        <selectKey keyProperty="id" order="AFTER" resultType="Long">
            SELECT LAST_INSERT_ID()
        </selectKey>
    </insert>
    
    <!-- 更新用户 -->
    <update id="update" parameterType="com.example.entity.User">
        UPDATE users
        <set>
            <if test="name != null">name = #{name},</if>
            <if test="email != null">email = #{email},</if>
        </set>
        WHERE id = #{id}
    </update>
    
    <!-- 删除用户 -->
    <delete id="delete" parameterType="Long">
        DELETE FROM users WHERE id = #{id}
    </delete>
    
    <!-- 动态SQL示例:条件查询 -->
    <select id="selectByCondition" parameterType="Map" resultMap="UserResultMap">
        SELECT * FROM users
        <where>
            <if test="name != null and name != ''">
                AND name LIKE CONCAT('%', #{name}, '%')
            </if>
            <if test="email != null and email != ''">
                AND email LIKE CONCAT('%', #{email}, '%')
            </if>
            <if test="startTime != null">
                AND create_time >= #{startTime}
            </if>
            <if test="endTime != null">
                AND create_time <= #{endTime}
            </if>
        </where>
    </select>
</mapper>
// Java代码示例
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MyBatisDemo {
    public static void main(String[] args) throws Exception {
        // 1. 加载MyBatis配置文件
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        
        // 2. 创建SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 3. 获取SqlSession
        try (SqlSession session = sqlSessionFactory.openSession()) {
            // 4. 获取Mapper接口
            UserMapper userMapper = session.getMapper(UserMapper.class);
            
            // 5. 执行数据库操作
            // 查询所有用户
            List<User> users = userMapper.selectAll();
            System.out.println("查询到 " + users.size() + " 个用户");
            
            // 根据ID查询用户
            User user = userMapper.selectById(1L);
            System.out.println("ID为1的用户: " + user);
            
            // 插入新用户
            User newUser = new User();
            newUser.setName("张三");
            newUser.setEmail("zhangsan@example.com");
            newUser.setCreateTime(new Date());
            userMapper.insert(newUser);
            System.out.println("新用户ID: " + newUser.getId());
            
            // 动态SQL查询
            Map<String, Object> condition = new HashMap<>();
            condition.put("name", "张");
            condition.put("startTime", "2023-01-01");
            List<User> filteredUsers = userMapper.selectByCondition(condition);
            System.out.println("条件查询结果: " + filteredUsers.size() + " 个用户");
            
            // 提交事务
            session.commit();
        }
    }
}

5.3 分布式系统基础

现代Java应用通常部署在分布式环境中,理解分布式系统基础是高级开发者的必备技能。

核心概念:

  • CAP定理:一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)
  • 分布式锁:解决分布式环境下的资源竞争问题
  • 分布式事务:保证跨多个服务的数据一致性
  • 服务发现与注册:如Eureka、Consul、Nacos

实战示例:

// 分布式锁示例(基于Redis)
public class RedisDistributedLock {
    private static final String LOCK_KEY = "distributed_lock";
    private static final long LOCK_EXPIRE_TIME = 30000; // 30秒
    
    // 使用Redisson客户端实现分布式锁
    public static void main(String[] args) {
        // 配置Redisson客户端
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        RedissonClient redisson = Redisson.create(config);
        
        // 获取分布式锁
        RLock lock = redisson.getLock(LOCK_KEY);
        
        try {
            // 尝试获取锁,最多等待10秒,锁自动释放时间30秒
            boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
            
            if (isLocked) {
                System.out.println("获取分布式锁成功,线程: " + Thread.currentThread().getName());
                
                // 执行关键业务逻辑
                System.out.println("执行业务操作...");
                Thread.sleep(5000);
                
                System.out.println("业务操作完成");
            } else {
                System.out.println("获取分布式锁失败");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
                System.out.println("释放分布式锁");
            }
        }
        
        redisson.shutdown();
    }
}

// 分布式事务示例(Seata)
// 1. 服务A(订单服务)
@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    
    @Autowired
    private AccountService accountService;
    
    @Autowired
    private StorageService storageService;
    
    @GlobalTransactional(name = "createOrder", rollbackFor = Exception.class)
    public void createOrder(Order order) {
        // 1. 创建订单
        orderMapper.insert(order);
        
        // 2. 扣减账户余额
        accountService.decrease(order.getUserId(), order.getAmount());
        
        // 3. 扣减库存
        storageService.decrease(order.getProductId(), order.getQuantity());
        
        System.out.println("订单创建成功: " + order.getId());
    }
}

// 2. 服务B(账户服务)
@Service
public class AccountService {
    @Autowired
    private AccountMapper accountMapper;
    
    @Transactional(rollbackFor = Exception.class)
    public void decrease(Long userId, BigDecimal amount) {
        // 扣减账户余额
        accountMapper.decrease(userId, amount);
        System.out.println("账户扣减成功: userId=" + userId + ", amount=" + amount);
    }
}

// 3. 服务C(库存服务)
@Service
public class StorageService {
    @Autowired
    private StorageMapper storageMapper;
    
    @Transactional(rollbackFor = Exception.class)
    public void decrease(Long productId, Integer quantity) {
        // 扣减库存
        storageMapper.decrease(productId, quantity);
        System.out.println("库存扣减成功: productId=" + productId + ", quantity=" + quantity);
    }
}

第六部分:实战项目与最佳实践

6.1 项目架构设计

分层架构示例:

├── controller/          # 控制层,处理HTTP请求
├── service/             # 业务逻辑层
├── repository/          # 数据访问层
├── entity/              # 实体类
├── dto/                 # 数据传输对象
├── config/              # 配置类
├── exception/           # 异常处理
└── util/                # 工具类

6.2 代码规范与设计模式

常用设计模式:

  • 单例模式:确保一个类只有一个实例
  • 工厂模式:创建对象而不指定具体类
  • 观察者模式:定义对象间的一对多依赖关系
  • 策略模式:定义一系列算法,封装每个算法
  • 装饰器模式:动态添加对象功能

实战示例:

// 策略模式示例:支付方式
interface PaymentStrategy {
    void pay(double amount);
}

class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    
    public CreditCardPayment(String cardNumber) {
        this.cardNumber = cardNumber;
    }
    
    @Override
    public void pay(double amount) {
        System.out.println("使用信用卡支付: " + amount + "元,卡号: " + cardNumber);
    }
}

class AlipayPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用支付宝支付: " + amount + "元");
    }
}

class WechatPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("使用微信支付: " + amount + "元");
    }
}

class PaymentContext {
    private PaymentStrategy strategy;
    
    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void executePayment(double amount) {
        if (strategy != null) {
            strategy.pay(amount);
        } else {
            System.out.println("未设置支付策略");
        }
    }
}

// 观察者模式示例:消息通知
interface Observer {
    void update(String message);
}

class EmailObserver implements Observer {
    private String email;
    
    public EmailObserver(String email) {
        this.email = email;
    }
    
    @Override
    public void update(String message) {
        System.out.println("发送邮件到 " + email + ": " + message);
    }
}

class SmsObserver implements Observer {
    private String phone;
    
    public SmsObserver(String phone) {
        this.phone = phone;
    }
    
    @Override
    public void update(String message) {
        System.out.println("发送短信到 " + phone + ": " + message);
    }
}

class Subject {
    private List<Observer> observers = new ArrayList<>();
    
    public void addObserver(Observer observer) {
        observers.add(observer);
    }
    
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }
    
    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

public class DesignPatternDemo {
    public static void main(String[] args) {
        // 策略模式演示
        PaymentContext context = new PaymentContext();
        
        context.setStrategy(new CreditCardPayment("1234-5678-9012-3456"));
        context.executePayment(100.0);
        
        context.setStrategy(new AlipayPayment());
        context.executePayment(200.0);
        
        context.setStrategy(new WechatPayment());
        context.executePayment(300.0);
        
        System.out.println("\n" + "=".repeat(50) + "\n");
        
        // 观察者模式演示
        Subject subject = new Subject();
        
        Observer emailObserver = new EmailObserver("user@example.com");
        Observer smsObserver = new SmsObserver("13800138000");
        
        subject.addObserver(emailObserver);
        subject.addObserver(smsObserver);
        
        subject.notifyObservers("系统维护通知:今晚10点系统将进行维护");
    }
}

6.3 单元测试与集成测试

测试框架:

  • JUnit 5:单元测试框架
  • Mockito:Mock框架,用于模拟依赖
  • Spring Test:Spring集成测试
  • Testcontainers:用于集成测试的容器化工具

实战示例:

// 单元测试示例
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    public int subtract(int a, int b) {
        return a - b;
    }
}

class CalculatorTest {
    private Calculator calculator;
    
    @BeforeEach
    void setUp() {
        calculator = new Calculator();
    }
    
    @Test
    @DisplayName("测试加法运算")
    void testAdd() {
        assertEquals(5, calculator.add(2, 3));
        assertEquals(0, calculator.add(-1, 1));
        assertEquals(10, calculator.add(5, 5));
    }
    
    @Test
    @DisplayName("测试减法运算")
    void testSubtract() {
        assertEquals(1, calculator.subtract(3, 2));
        assertEquals(-2, calculator.subtract(1, 3));
        assertEquals(0, calculator.subtract(5, 5));
    }
    
    @Test
    @DisplayName("测试边界情况")
    void testBoundaryCases() {
        // 测试最大值
        assertEquals(Integer.MAX_VALUE, calculator.add(Integer.MAX_VALUE, 0));
        
        // 测试最小值
        assertEquals(Integer.MIN_VALUE, calculator.add(Integer.MIN_VALUE, 0));
    }
}

// Mockito示例
import org.junit.jupiter.api.Test;
import org.mockito.*;

class UserService {
    private UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public User getUserById(Long id) {
        return userRepository.findById(id);
    }
    
    public User createUser(User user) {
        return userRepository.save(user);
    }
}

interface UserRepository {
    User findById(Long id);
    User save(User user);
}

class UserServiceTest {
    @Mock
    private UserRepository userRepository;
    
    @InjectMocks
    private UserService userService;
    
    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
    }
    
    @Test
    void testGetUserById() {
        // 准备测试数据
        User mockUser = new User();
        mockUser.setId(1L);
        mockUser.setName("Test User");
        
        // 模拟行为
        when(userRepository.findById(1L)).thenReturn(mockUser);
        
        // 执行测试
        User result = userService.getUserById(1L);
        
        // 验证结果
        assertNotNull(result);
        assertEquals(1L, result.getId());
        assertEquals("Test User", result.getName());
        
        // 验证方法调用
        verify(userRepository, times(1)).findById(1L);
    }
    
    @Test
    void testCreateUser() {
        User userToCreate = new User();
        userToCreate.setName("New User");
        
        User savedUser = new User();
        savedUser.setId(100L);
        savedUser.setName("New User");
        
        when(userRepository.save(userToCreate)).thenReturn(savedUser);
        
        User result = userService.createUser(userToCreate);
        
        assertNotNull(result);
        assertEquals(100L, result.getId());
        assertEquals("New User", result.getName());
        
        verify(userRepository, times(1)).save(userToCreate);
    }
}

第七部分:持续学习与资源推荐

7.1 学习路径建议

  1. 基础阶段(1-2个月)

    • Java核心语法、OOP、集合框架、异常处理
    • 完成5-10个小型控制台项目
  2. 进阶阶段(2-3个月)

    • 泛型、反射、注解、并发编程
    • 学习Spring Boot基础
    • 完成1-2个Web应用项目
  3. 高级阶段(3-6个月)

    • JVM原理与性能调优
    • 分布式系统基础
    • 微服务架构
    • 完成1个完整的分布式系统项目
  4. 专家阶段(持续学习)

    • 深入研究特定领域(如大数据、AI、区块链)
    • 参与开源项目
    • 撰写技术博客和文章

7.2 推荐资源

书籍推荐:

  • 《Java核心技术》(Core Java)
  • 《Effective Java》
  • 《Java并发编程实战》
  • 《深入理解Java虚拟机》
  • 《Spring实战》
  • 《微服务架构设计模式》

在线课程:

  • Coursera: “Java Programming and Software Engineering Fundamentals”
  • Udemy: “Java Programming Masterclass”
  • 极客时间: “Java核心技术36讲”
  • 慕课网: “Java高级开发实战”

开源项目:

  • Spring Framework
  • Apache Commons
  • Guava
  • Netty
  • Elasticsearch

技术社区:

  • Stack Overflow
  • GitHub
  • CSDN
  • 掘金
  • 知乎

7.3 实践建议

  1. 每日编码:坚持每天写代码,哪怕只有30分钟
  2. 代码审查:学习阅读和审查他人代码
  3. 参与开源:从修复小bug开始参与开源项目
  4. 技术分享:定期整理学习笔记并分享
  5. 解决问题:主动解决实际问题,而不仅仅是学习理论

结语

Java高级学习是一个循序渐进的过程,需要理论与实践相结合。通过本指南提供的系统学习路径和实战示例,你可以逐步掌握Java的核心概念与高级技巧。记住,编程是一门实践的艺术,只有通过不断的编码、调试和优化,才能真正成为Java专家。保持好奇心,持续学习,勇于实践,你一定能在Java开发的道路上越走越远。