引言

Java作为一种广泛使用的编程语言,自1995年由Sun Microsystems(现为Oracle公司)发布以来,已经发展成为企业级应用、移动开发(Android)、大数据处理和云计算等领域的主流语言。其“一次编写,到处运行”(Write Once, Run Anywhere)的特性得益于Java虚拟机(JVM),使得Java程序可以在不同操作系统上无缝运行。对于初学者来说,Java的学习曲线相对平缓,但要达到精通水平,需要系统性的学习和大量的实战练习。本指南将从基础概念讲起,逐步深入到高级主题,并通过完整的实战案例帮助读者巩固知识。无论你是编程新手还是有一定经验的开发者,这份指南都能为你提供清晰的学习路径和实用的资源。

第一部分:Java基础入门

1.1 Java简介与环境搭建

Java是一种面向对象的编程语言,具有封装、继承和多态等核心特性。要开始学习Java,首先需要搭建开发环境。推荐使用JDK(Java Development Kit)17或更高版本,因为Java 17是长期支持(LTS)版本,适用于生产环境。

步骤1:下载并安装JDK

  • 访问Oracle官网或OpenJDK项目(如Adoptium)下载JDK。例如,对于Windows用户,可以从Adoptium下载Eclipse Temurin JDK 17。
  • 安装后,配置环境变量:
    • 在Windows中,右键“此电脑” -> “属性” -> “高级系统设置” -> “环境变量”,在“系统变量”中添加JAVA_HOME,值为JDK安装路径(如C:\Program Files\Eclipse Adoptium\jdk-17.0.10.7-hotspot),并在Path变量中添加%JAVA_HOME%\bin
    • 在macOS或Linux中,编辑~/.bash_profile~/.zshrc,添加export JAVA_HOME=/path/to/jdkexport PATH=$JAVA_HOME/bin:$PATH,然后运行source ~/.bash_profile

步骤2:验证安装 打开命令行,输入java -versionjavac -version,应显示类似以下输出:

java version "17.0.10" 2024-01-16 LTS
Java(TM) SE Runtime Environment (build 17.0.10+7-LTS-224)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.10+7-LTS-224, mixed mode, sharing)

步骤3:选择IDE 推荐使用IntelliJ IDEA(社区版免费)或Eclipse。IntelliJ IDEA对Java支持更友好,提供智能代码补全和调试工具。安装后,创建一个新项目,选择Java SDK版本为17。

1.2 Java基本语法

Java程序的基本结构是类(Class)和方法(Method)。每个Java程序必须有一个main方法作为入口点。

示例:Hello World程序 创建一个名为HelloWorld.java的文件,内容如下:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
  • public class HelloWorld:定义一个公共类,类名必须与文件名一致。
  • public static void main(String[] args):主方法,程序从这里开始执行。
  • System.out.println:输出字符串到控制台。

编译和运行 在命令行中,导航到文件所在目录,执行:

javac HelloWorld.java  // 编译生成HelloWorld.class字节码文件
java HelloWorld        // 运行程序,输出"Hello, World!"

变量与数据类型 Java是强类型语言,变量必须声明类型。基本数据类型包括:

  • 整数:byte(8位)、short(16位)、int(32位)、long(64位)。
  • 浮点数:float(32位)、double(64位)。
  • 字符:char(16位Unicode字符)。
  • 布尔:boolean(true或false)。

示例:变量声明

public class Variables {
    public static void main(String[] args) {
        int age = 25;           // 整数变量
        double salary = 5000.5; // 浮点数变量
        char grade = 'A';       // 字符变量
        boolean isStudent = true; // 布尔变量
        System.out.println("Age: " + age + ", Salary: " + salary);
    }
}

运算符 Java支持算术运算符(+、-、*、/、%)、关系运算符(==、!=、>、<、>=、<=)、逻辑运算符(&&、||、!)等。

示例:运算符使用

public class Operators {
    public static void main(String[] args) {
        int a = 10, b = 3;
        System.out.println("a + b = " + (a + b));  // 13
        System.out.println("a % b = " + (a % b));  // 1 (余数)
        System.out.println("a > b: " + (a > b));   // true
    }
}

1.3 控制流语句

控制流语句用于控制程序的执行顺序,包括条件语句和循环语句。

if-else语句

public class IfElseExample {
    public static void main(String[] args) {
        int score = 85;
        if (score >= 90) {
            System.out.println("优秀");
        } else if (score >= 60) {
            System.out.println("及格");
        } else {
            System.out.println("不及格");
        }
    }
}

switch语句 Java 12引入了增强的switch表达式,但传统switch仍常用。

public class SwitchExample {
    public static void main(String[] args) {
        int day = 3;
        String dayName;
        switch (day) {
            case 1: dayName = "Monday"; break;
            case 2: dayName = "Tuesday"; break;
            case 3: dayName = "Wednesday"; break;
            default: dayName = "Invalid day";
        }
        System.out.println(dayName);
    }
}

循环语句

  • for循环:用于已知迭代次数。
  • while循环:用于条件满足时重复执行。
  • do-while循环:至少执行一次。

示例:for循环计算1到10的和

public class ForLoopExample {
    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 10; i++) {
            sum += i;
        }
        System.out.println("Sum: " + sum); // 55
    }
}

增强for循环(for-each) 用于遍历数组或集合。

public class ForEachExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5};
        for (int num : numbers) {
            System.out.print(num + " ");
        }
    }
}

1.4 数组

数组是固定大小的同类型元素集合。

一维数组

public class ArrayExample {
    public static void main(String[] args) {
        int[] scores = new int[3]; // 声明并初始化大小为3的数组
        scores[0] = 90;
        scores[1] = 85;
        scores[2] = 78;
        // 遍历数组
        for (int i = 0; i < scores.length; i++) {
            System.out.println("Score " + i + ": " + scores[i]);
        }
    }
}

二维数组

public class TwoDArrayExample {
    public static void main(String[] args) {
        int[][] matrix = {{1, 2}, {3, 4}, {5, 6}};
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                System.out.print(matrix[i][j] + " ");
            }
            System.out.println();
        }
    }
}

1.5 方法

方法是执行特定任务的代码块。Java方法可以有参数和返回值。

示例:定义和调用方法

public class MethodExample {
    // 定义一个方法,计算两个整数的和
    public static int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        int result = add(5, 3);
        System.out.println("5 + 3 = " + result);
    }
}

方法重载 同一个类中,方法名相同但参数列表不同。

public class OverloadExample {
    public static int add(int a, int b) {
        return a + b;
    }

    public static double add(double a, double b) {
        return a + b;
    }

    public static void main(String[] args) {
        System.out.println(add(5, 3));     // 调用int版本
        System.out.println(add(5.5, 3.2)); // 调用double版本
    }
}

第二部分:面向对象编程(OOP)

2.1 类与对象

类是对象的蓝图,对象是类的实例。

示例:定义一个Person类

public class Person {
    // 成员变量(属性)
    private String name;
    private int age;

    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 成员方法
    public void introduce() {
        System.out.println("我叫" + name + ",今年" + 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) {
        if (age > 0) {
            this.age = age;
        }
    }
}

创建和使用对象

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 25);
        person.introduce(); // 输出:我叫Alice,今年25岁。
        person.setAge(26);
        System.out.println("更新后的年龄: " + person.getAge());
    }
}

2.2 封装

封装是将数据(变量)和操作数据的方法绑定在一起,并隐藏内部实现细节。通过访问修饰符(private、protected、public)控制访问。

示例:银行账户类

public 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;
    }
}

使用BankAccount类

public class BankMain {
    public static void main(String[] args) {
        BankAccount account = new BankAccount(1000);
        account.deposit(500);
        account.withdraw(200);
        System.out.println("最终余额: " + account.getBalance());
    }
}

2.3 继承

继承允许子类继承父类的属性和方法,实现代码重用。Java使用extends关键字实现单继承(一个类只能继承一个父类)。

示例:动物继承体系

// 父类
class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }

    public void eat() {
        System.out.println(name + " is eating.");
    }

    public void sleep() {
        System.out.println(name + " is sleeping.");
    }
}

// 子类Dog
class Dog extends Animal {
    public Dog(String name) {
        super(name); // 调用父类构造方法
    }

    public void bark() {
        System.out.println(name + " barks: Woof!");
    }
}

// 子类Cat
class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }

    public void meow() {
        System.out.println(name + " meows: Meow!");
    }
}

使用继承

public class InheritanceMain {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        dog.eat();  // 继承自Animal
        dog.bark(); // Dog特有方法

        Cat cat = new Cat("Whiskers");
        cat.sleep(); // 继承自Animal
        cat.meow();  // Cat特有方法
    }
}

2.4 多态

多态允许父类引用指向子类对象,通过方法重写(Override)实现运行时绑定。

示例:方法重写

class Shape {
    public void draw() {
        System.out.println("Drawing a shape");
    }
}

class Circle extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a circle");
    }
}

class Square extends Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a square");
    }
}

多态示例

public class PolymorphismMain {
    public static void main(String[] args) {
        Shape shape1 = new Circle(); // 父类引用指向子类对象
        Shape shape2 = new Square();

        shape1.draw(); // 输出:Drawing a circle
        shape2.draw(); // 输出:Drawing a square

        // 多态数组
        Shape[] shapes = {new Circle(), new Square()};
        for (Shape shape : shapes) {
            shape.draw(); // 运行时根据实际类型调用方法
        }
    }
}

2.5 抽象类与接口

抽象类 抽象类不能被实例化,可以包含抽象方法(没有实现的方法)和具体方法。

abstract class AbstractAnimal {
    protected String name;

    public AbstractAnimal(String name) {
        this.name = name;
    }

    // 抽象方法,子类必须实现
    public abstract void makeSound();

    // 具体方法
    public void sleep() {
        System.out.println(name + " is sleeping.");
    }
}

class Dog extends AbstractAnimal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println("Woof!");
    }
}

接口 接口是完全抽象的,Java 8后接口可以有默认方法和静态方法。接口用于定义行为契约。

interface Flyable {
    void fly(); // 抽象方法
    default void takeoff() {
        System.out.println("Taking off...");
    }
}

class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("Bird is flying");
    }
}

class Airplane implements Flyable {
    @Override
    public void fly() {
        System.out.println("Airplane is flying");
    }
}

使用接口

public class InterfaceMain {
    public static void main(String[] args) {
        Flyable bird = new Bird();
        bird.fly();
        bird.takeoff();

        Flyable plane = new Airplane();
        plane.fly();
    }
}

第三部分:Java核心API与高级特性

3.1 字符串处理

Java中字符串是不可变的,使用String类。常用方法包括length()charAt()substring()equals()concat()等。

示例:字符串操作

public class StringExample {
    public static void main(String[] args) {
        String str = "Hello, Java!";
        System.out.println("Length: " + str.length()); // 12
        System.out.println("Substring: " + str.substring(7, 11)); // "Java"
        System.out.println("Uppercase: " + str.toUpperCase()); // "HELLO, JAVA!"
        
        // 字符串比较
        String str1 = "hello";
        String str2 = "hello";
        System.out.println(str1.equals(str2)); // true (内容比较)
        System.out.println(str1 == str2);      // true (因为字符串常量池,但一般不推荐用==)
        
        // StringBuilder用于可变字符串
        StringBuilder sb = new StringBuilder("Hello");
        sb.append(" World!");
        System.out.println(sb.toString()); // "Hello World!"
    }
}

3.2 集合框架

Java集合框架(Collections Framework)提供了一系列接口和类来存储和操作数据。主要接口包括ListSetMap

List接口:有序、可重复的集合。常用实现类:ArrayListLinkedList

import java.util.ArrayList;
import java.util.List;

public class ListExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");
        list.add("Apple"); // 允许重复

        System.out.println("List: " + list); // [Apple, Banana, Cherry, Apple]
        System.out.println("Element at index 1: " + list.get(1)); // Banana
        list.remove("Apple"); // 删除第一个Apple
        System.out.println("After removal: " + list); // [Banana, Cherry, Apple]
    }
}

Set接口:无序、不重复的集合。常用实现类:HashSetTreeSet

import java.util.HashSet;
import java.util.Set;

public class SetExample {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("Apple");
        set.add("Banana");
        set.add("Cherry");
        set.add("Apple"); // 重复元素不会被添加

        System.out.println("Set: " + set); // [Banana, Cherry, Apple] (顺序不固定)
        System.out.println("Contains Apple? " + set.contains("Apple")); // true
    }
}

Map接口:键值对映射。常用实现类:HashMapTreeMap

import java.util.HashMap;
import java.util.Map;

public class MapExample {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<>();
        map.put("Alice", 25);
        map.put("Bob", 30);
        map.put("Charlie", 35);

        System.out.println("Map: " + map); // {Alice=25, Bob=30, Charlie=35}
        System.out.println("Alice's age: " + map.get("Alice")); // 25
        map.remove("Bob");
        System.out.println("After removal: " + map); // {Alice=25, Charlie=35}
    }
}

3.3 异常处理

Java异常处理使用try-catch-finally块。异常分为检查型异常(Checked Exception)和非检查型异常(Unchecked Exception)。

示例:处理除零异常

public class ExceptionExample {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        try {
            int result = a / b;
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("Error: Division by zero");
            e.printStackTrace(); // 打印异常堆栈
        } finally {
            System.out.println("This block always executes");
        }
    }
}

自定义异常

class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

class BankAccount {
    private double balance;

    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException("Insufficient funds: " + balance);
        }
        balance -= amount;
    }
}

3.4 泛型

泛型提供类型安全,避免运行时类型转换错误。

示例:泛型类

public class Box<T> {
    private T content;

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

    public T getContent() {
        return content;
    }
}

public class GenericExample {
    public static void main(String[] args) {
        Box<String> stringBox = new Box<>();
        stringBox.setContent("Hello");
        System.out.println(stringBox.getContent()); // Hello

        Box<Integer> intBox = new Box<>();
        intBox.setContent(123);
        System.out.println(intBox.getContent()); // 123
    }
}

3.5 输入输出(I/O)

Java I/O使用流(Stream)概念。字节流(InputStream/OutputStream)用于二进制数据,字符流(Reader/Writer)用于文本数据。

示例:文件读写

import java.io.*;

public class FileIOExample {
    public static void main(String[] args) {
        // 写入文件
        try (FileWriter writer = new FileWriter("test.txt")) {
            writer.write("Hello, Java I/O!");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 读取文件
        try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.6 多线程

Java通过Thread类和Runnable接口实现多线程。

示例:使用Thread类

public class ThreadExample extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }

    public static void main(String[] args) {
        ThreadExample thread1 = new ThreadExample();
        ThreadExample thread2 = new ThreadExample();
        thread1.start();
        thread2.start();
    }
}

示例:使用Runnable接口

public class RunnableExample implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }

    public static void main(String[] args) {
        RunnableExample runnable = new RunnableExample();
        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        thread1.start();
        thread2.start();
    }
}

线程同步 使用synchronized关键字防止线程安全问题。

public class Counter {
    private int count = 0;

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

    public int getCount() {
        return count;
    }
}

3.7 反射

反射允许在运行时检查和修改类、方法、字段等。

示例:反射获取类信息

import java.lang.reflect.*;

public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("java.lang.String");
        System.out.println("Class name: " + clazz.getName());

        // 获取构造方法
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("Constructor: " + constructor);
        }

        // 获取方法
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println("Method: " + method.getName());
        }
    }
}

第四部分:Java高级主题

4.1 Java 8新特性

Lambda表达式 Lambda表达式简化匿名内部类的写法。

import java.util.Arrays;
import java.util.List;

public class LambdaExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
        // 使用Lambda表达式遍历
        names.forEach(name -> System.out.println(name));
        
        // 使用方法引用
        names.forEach(System.out::println);
    }
}

Stream API Stream API用于处理集合数据,支持函数式编程。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        // 过滤偶数并收集到新列表
        List<Integer> evenNumbers = numbers.stream()
                                           .filter(n -> n % 2 == 0)
                                           .collect(Collectors.toList());
        System.out.println("Even numbers: " + evenNumbers); // [2, 4, 6, 8, 10]
        
        // 计算平方和
        int sumOfSquares = numbers.stream()
                                  .map(n -> n * n)
                                  .reduce(0, Integer::sum);
        System.out.println("Sum of squares: " + sumOfSquares); // 385
    }
}

Optional类 Optional用于避免空指针异常。

import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        String name = "Alice";
        Optional<String> optionalName = Optional.ofNullable(name);
        
        if (optionalName.isPresent()) {
            System.out.println("Name: " + optionalName.get());
        }
        
        // 使用orElse提供默认值
        String nullName = null;
        Optional<String> optionalNull = Optional.ofNullable(nullName);
        System.out.println("Name: " + optionalNull.orElse("Unknown"));
    }
}

4.2 Java 11+新特性

局部变量类型推断(var) Java 10引入了var关键字,允许局部变量类型推断。

public class VarExample {
    public static void main(String[] args) {
        var name = "Alice"; // 编译器推断为String
        var age = 25;       // 编译器推断为int
        System.out.println(name + " is " + age + " years old.");
    }
}

HTTP Client API Java 11引入了新的HTTP客户端API。

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class HttpClientExample {
    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://httpbin.org/get"))
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());
    }
}

4.3 Java内存模型与垃圾回收

Java内存模型(JMM)定义了线程如何与主内存交互。垃圾回收(GC)自动管理内存,常见的GC算法包括标记-清除、复制、标记-整理等。

示例:观察GC行为

public class GCExample {
    public static void main(String[] args) {
        for (int i = 0; i < 1000000; i++) {
            new Object(); // 创建大量对象,触发GC
        }
        System.gc(); // 建议JVM进行垃圾回收
        System.out.println("GC suggested");
    }
}

4.4 并发编程高级主题

ExecutorService 用于管理线程池。

import java.util.concurrent.*;

public class ExecutorServiceExample {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
            });
        }
        
        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.MINUTES);
    }
}

CompletableFuture 用于异步编程。

import java.util.concurrent.CompletableFuture;

public class CompletableFutureExample {
    public static void main(String[] args) {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "Hello";
        });
        
        future.thenAccept(result -> System.out.println("Result: " + result));
        
        // 阻塞直到完成
        future.join();
    }
}

第五部分:实战案例解析

5.1 案例1:简单计算器

需求:实现一个命令行计算器,支持加、减、乘、除。

代码实现

import java.util.Scanner;

public class Calculator {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter first number:");
        double num1 = scanner.nextDouble();
        System.out.println("Enter operator (+, -, *, /):");
        char operator = scanner.next().charAt(0);
        System.out.println("Enter second number:");
        double num2 = scanner.nextDouble();

        double result = 0;
        boolean valid = true;

        switch (operator) {
            case '+':
                result = num1 + num2;
                break;
            case '-':
                result = num1 - num2;
                break;
            case '*':
                result = num1 * num2;
                break;
            case '/':
                if (num2 != 0) {
                    result = num1 / num2;
                } else {
                    System.out.println("Error: Division by zero");
                    valid = false;
                }
                break;
            default:
                System.out.println("Error: Invalid operator");
                valid = false;
        }

        if (valid) {
            System.out.println("Result: " + result);
        }

        scanner.close();
    }
}

运行示例

Enter first number: 10
Enter operator (+, -, *, /): *
Enter second number: 5
Result: 50.0

5.2 案例2:学生管理系统

需求:实现一个控制台学生管理系统,支持添加、删除、查询和显示学生信息。

代码实现

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Student {
    private String id;
    private String name;
    private int age;

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

    public String getId() { return id; }
    public String getName() { return name; }
    public int getAge() { return age; }

    @Override
    public String toString() {
        return "ID: " + id + ", Name: " + name + ", Age: " + age;
    }
}

public class StudentManager {
    private List<Student> students = new ArrayList<>();
    private Scanner scanner = new Scanner(System.in);

    public void addStudent() {
        System.out.println("Enter student ID:");
        String id = scanner.nextLine();
        System.out.println("Enter student name:");
        String name = scanner.nextLine();
        System.out.println("Enter student age:");
        int age = scanner.nextInt();
        scanner.nextLine(); // consume newline

        students.add(new Student(id, name, age));
        System.out.println("Student added successfully.");
    }

    public void deleteStudent() {
        System.out.println("Enter student ID to delete:");
        String id = scanner.nextLine();
        boolean found = false;
        for (Student student : students) {
            if (student.getId().equals(id)) {
                students.remove(student);
                found = true;
                System.out.println("Student deleted successfully.");
                break;
            }
        }
        if (!found) {
            System.out.println("Student not found.");
        }
    }

    public void searchStudent() {
        System.out.println("Enter student ID to search:");
        String id = scanner.nextLine();
        for (Student student : students) {
            if (student.getId().equals(id)) {
                System.out.println(student);
                return;
            }
        }
        System.out.println("Student not found.");
    }

    public void displayAll() {
        if (students.isEmpty()) {
            System.out.println("No students in the system.");
        } else {
            for (Student student : students) {
                System.out.println(student);
            }
        }
    }

    public void run() {
        while (true) {
            System.out.println("\n--- Student Management System ---");
            System.out.println("1. Add Student");
            System.out.println("2. Delete Student");
            System.out.println("3. Search Student");
            System.out.println("4. Display All");
            System.out.println("5. Exit");
            System.out.print("Choose an option: ");

            int choice = scanner.nextInt();
            scanner.nextLine(); // consume newline

            switch (choice) {
                case 1:
                    addStudent();
                    break;
                case 2:
                    deleteStudent();
                    break;
                case 3:
                    searchStudent();
                    break;
                case 4:
                    displayAll();
                    break;
                case 5:
                    System.out.println("Exiting...");
                    scanner.close();
                    return;
                default:
                    System.out.println("Invalid option. Please try again.");
            }
        }
    }

    public static void main(String[] args) {
        StudentManager manager = new StudentManager();
        manager.run();
    }
}

运行示例

--- Student Management System ---
1. Add Student
2. Delete Student
3. Search Student
4. Display All
5. Exit
Choose an option: 1
Enter student ID: S001
Enter student name: Alice
Enter student age: 20
Student added successfully.

5.3 案例3:简易银行账户系统(使用OOP和异常处理)

需求:实现一个银行账户系统,支持存款、取款、查询余额,处理异常情况(如余额不足)。

代码实现

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

class BankAccount {
    private String accountNumber;
    private double balance;
    private String ownerName;

    public BankAccount(String accountNumber, String ownerName, double initialBalance) {
        this.accountNumber = accountNumber;
        this.ownerName = ownerName;
        this.balance = initialBalance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposit successful. New balance: " + balance);
        } else {
            System.out.println("Invalid deposit amount.");
        }
    }

    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount <= 0) {
            System.out.println("Invalid withdrawal amount.");
            return;
        }
        if (amount > balance) {
            throw new InsufficientFundsException("Insufficient funds. Current balance: " + balance);
        }
        balance -= amount;
        System.out.println("Withdrawal successful. New balance: " + balance);
    }

    public double getBalance() {
        return balance;
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public String getOwnerName() {
        return ownerName;
    }

    @Override
    public String toString() {
        return "Account: " + accountNumber + ", Owner: " + ownerName + ", Balance: " + balance;
    }
}

public class BankSystem {
    private List<BankAccount> accounts = new ArrayList<>();
    private Scanner scanner = new Scanner(System.in);

    public void createAccount() {
        System.out.println("Enter account number:");
        String accNum = scanner.nextLine();
        System.out.println("Enter owner name:");
        String owner = scanner.nextLine();
        System.out.println("Enter initial balance:");
        double balance = scanner.nextDouble();
        scanner.nextLine(); // consume newline

        BankAccount account = new BankAccount(accNum, owner, balance);
        accounts.add(account);
        System.out.println("Account created successfully.");
    }

    public BankAccount findAccount(String accNum) {
        for (BankAccount acc : accounts) {
            if (acc.getAccountNumber().equals(accNum)) {
                return acc;
            }
        }
        return null;
    }

    public void deposit() {
        System.out.println("Enter account number:");
        String accNum = scanner.nextLine();
        BankAccount account = findAccount(accNum);
        if (account == null) {
            System.out.println("Account not found.");
            return;
        }
        System.out.println("Enter amount to deposit:");
        double amount = scanner.nextDouble();
        scanner.nextLine();
        account.deposit(amount);
    }

    public void withdraw() {
        System.out.println("Enter account number:");
        String accNum = scanner.nextLine();
        BankAccount account = findAccount(accNum);
        if (account == null) {
            System.out.println("Account not found.");
            return;
        }
        System.out.println("Enter amount to withdraw:");
        double amount = scanner.nextDouble();
        scanner.nextLine();
        try {
            account.withdraw(amount);
        } catch (InsufficientFundsException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }

    public void checkBalance() {
        System.out.println("Enter account number:");
        String accNum = scanner.nextLine();
        BankAccount account = findAccount(accNum);
        if (account == null) {
            System.out.println("Account not found.");
            return;
        }
        System.out.println("Current balance: " + account.getBalance());
    }

    public void run() {
        while (true) {
            System.out.println("\n--- Bank System ---");
            System.out.println("1. Create Account");
            System.out.println("2. Deposit");
            System.out.println("3. Withdraw");
            System.out.println("4. Check Balance");
            System.out.println("5. Exit");
            System.out.print("Choose an option: ");

            int choice = scanner.nextInt();
            scanner.nextLine(); // consume newline

            switch (choice) {
                case 1:
                    createAccount();
                    break;
                case 2:
                    deposit();
                    break;
                case 3:
                    withdraw();
                    break;
                case 4:
                    checkBalance();
                    break;
                case 5:
                    System.out.println("Exiting...");
                    scanner.close();
                    return;
                default:
                    System.out.println("Invalid option. Please try again.");
            }
        }
    }

    public static void main(String[] args) {
        BankSystem system = new BankSystem();
        system.run();
    }
}

运行示例

--- Bank System ---
1. Create Account
2. Deposit
3. Withdraw
4. Check Balance
5. Exit
Choose an option: 1
Enter account number: ACC001
Enter owner name: Alice
Enter initial balance: 1000
Account created successfully.

5.4 案例4:简易图书管理系统(使用集合和文件I/O)

需求:实现一个图书管理系统,支持添加、删除、查询图书,并将数据持久化到文件。

代码实现

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Book {
    private String isbn;
    private String title;
    private String author;
    private double price;

    public Book(String isbn, String title, String author, double price) {
        this.isbn = isbn;
        this.title = title;
        this.author = author;
        this.price = price;
    }

    public String getIsbn() { return isbn; }
    public String getTitle() { return title; }
    public String getAuthor() { return author; }
    public double getPrice() { return price; }

    @Override
    public String toString() {
        return "ISBN: " + isbn + ", Title: " + title + ", Author: " + author + ", Price: $" + price;
    }
}

public class BookManager {
    private List<Book> books = new ArrayList<>();
    private Scanner scanner = new Scanner(System.in);
    private static final String FILE_NAME = "books.txt";

    public void addBook() {
        System.out.println("Enter ISBN:");
        String isbn = scanner.nextLine();
        System.out.println("Enter title:");
        String title = scanner.nextLine();
        System.out.println("Enter author:");
        String author = scanner.nextLine();
        System.out.println("Enter price:");
        double price = scanner.nextDouble();
        scanner.nextLine(); // consume newline

        books.add(new Book(isbn, title, author, price));
        System.out.println("Book added successfully.");
    }

    public void deleteBook() {
        System.out.println("Enter ISBN to delete:");
        String isbn = scanner.nextLine();
        boolean found = false;
        for (Book book : books) {
            if (book.getIsbn().equals(isbn)) {
                books.remove(book);
                found = true;
                System.out.println("Book deleted successfully.");
                break;
            }
        }
        if (!found) {
            System.out.println("Book not found.");
        }
    }

    public void searchBook() {
        System.out.println("Enter ISBN to search:");
        String isbn = scanner.nextLine();
        for (Book book : books) {
            if (book.getIsbn().equals(isbn)) {
                System.out.println(book);
                return;
            }
        }
        System.out.println("Book not found.");
    }

    public void displayAll() {
        if (books.isEmpty()) {
            System.out.println("No books in the system.");
        } else {
            for (Book book : books) {
                System.out.println(book);
            }
        }
    }

    public void saveToFile() {
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(FILE_NAME))) {
            oos.writeObject(books);
            System.out.println("Data saved to file.");
        } catch (IOException e) {
            System.out.println("Error saving data: " + e.getMessage());
        }
    }

    @SuppressWarnings("unchecked")
    public void loadFromFile() {
        File file = new File(FILE_NAME);
        if (!file.exists()) {
            System.out.println("No saved data found.");
            return;
        }
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(FILE_NAME))) {
            books = (List<Book>) ois.readObject();
            System.out.println("Data loaded from file.");
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("Error loading data: " + e.getMessage());
        }
    }

    public void run() {
        loadFromFile(); // Load data on startup
        while (true) {
            System.out.println("\n--- Book Management System ---");
            System.out.println("1. Add Book");
            System.out.println("2. Delete Book");
            System.out.println("3. Search Book");
            System.out.println("4. Display All");
            System.out.println("5. Save to File");
            System.out.println("6. Exit");
            System.out.print("Choose an option: ");

            int choice = scanner.nextInt();
            scanner.nextLine(); // consume newline

            switch (choice) {
                case 1:
                    addBook();
                    break;
                case 2:
                    deleteBook();
                    break;
                case 3:
                    searchBook();
                    break;
                case 4:
                    displayAll();
                    break;
                case 5:
                    saveToFile();
                    break;
                case 6:
                    saveToFile(); // Auto-save on exit
                    System.out.println("Exiting...");
                    scanner.close();
                    return;
                default:
                    System.out.println("Invalid option. Please try again.");
            }
        }
    }

    public static void main(String[] args) {
        BookManager manager = new BookManager();
        manager.run();
    }
}

运行示例

--- Book Management System ---
1. Add Book
2. Delete Book
3. Search Book
4. Display All
5. Save to File
6. Exit
Choose an option: 1
Enter ISBN: 978-0134685991
Enter title: Effective Java
Enter author: Joshua Bloch
Enter price: 45.99
Book added successfully.

第六部分:学习资源与进阶路径

6.1 推荐学习资源

书籍

  • 《Java核心技术 卷I:基础知识》(Cay S. Horstmann):适合初学者,全面覆盖Java基础。
  • 《Effective Java》(Joshua Bloch):深入讲解Java最佳实践,适合中级开发者。
  • 《Java并发编程实战》(Brian Goetz等):深入理解多线程和并发。
  • 《Java性能权威指南》(Scott Oaks):优化Java应用性能。

在线课程

  • Coursera:《Java Programming and Software Engineering Fundamentals》(Duke University)。
  • Udemy:《Java Programming Masterclass》(Tim Buchalka)。
  • edX:《Introduction to Java Programming》(UC Berkeley)。

官方文档

社区与论坛

  • Stack Overflow:解决具体编程问题。
  • Reddit的r/java:讨论Java新闻和趋势。
  • GitHub:参与开源项目,如Apache Commons、Spring Framework。

6.2 进阶路径

  1. Web开发:学习Spring Boot、Spring MVC、RESTful API开发。推荐书籍《Spring in Action》。
  2. 移动开发:学习Android开发,使用Java或Kotlin。推荐资源:Android官方文档。
  3. 大数据:学习Hadoop、Spark(Java API)。推荐书籍《Hadoop: The Definitive Guide》。
  4. 微服务与云原生:学习Spring Cloud、Docker、Kubernetes。推荐课程:《Microservices with Spring Boot》。
  5. 性能优化与JVM调优:深入学习JVM内存模型、GC算法、性能监控工具(如JVisualVM、JProfiler)。

6.3 实战项目建议

  1. 个人博客系统:使用Spring Boot + Thymeleaf + MySQL,实现用户认证、文章发布、评论功能。
  2. 电商后台管理系统:使用Spring Boot + MyBatis + Vue.js,实现商品管理、订单处理、用户管理。
  3. 即时通讯应用:使用Netty或Spring WebSocket,实现私聊、群聊、文件传输。
  4. 数据可视化平台:使用Java后端 + ECharts,展示实时数据图表。
  5. 自动化测试框架:基于JUnit和Selenium,构建Web自动化测试工具。

结语

Java学习是一个循序渐进的过程,从基础语法到高级特性,再到实战项目,每一步都需要扎实的练习和思考。本指南提供了从入门到精通的完整路径,涵盖了核心概念、API使用、高级主题和实战案例。通过不断编写代码、参与项目和阅读源码,你将逐步掌握Java编程的精髓。记住,编程是一门实践的艺术,多写代码、多调试、多总结,才能不断进步。祝你在Java学习之旅中取得成功!