引言

Java作为一种历史悠久且广泛使用的编程语言,至今仍在企业级应用、安卓开发、大数据和云计算等领域占据重要地位。对于初学者来说,Java的强类型、面向对象和跨平台特性既是优势也是挑战。本指南将带你从零基础开始,逐步掌握Java核心概念,并通过实战项目巩固所学知识,最终达到能够独立开发项目的水平。

第一部分:Java基础入门

1.1 环境搭建

在开始编程之前,我们需要安装必要的开发工具。

JDK安装

  • 访问Oracle官网或OpenJDK项目下载适合你操作系统的JDK版本(推荐JDK 11或17)。
  • 安装后配置环境变量:
    • Windows:在系统变量中添加JAVA_HOME指向JDK安装路径,并将%JAVA_HOME%\bin添加到Path变量中。
    • macOS/Linux:在~/.bash_profile~/.zshrc中添加:
    export JAVA_HOME=/path/to/your/jdk
    export PATH=$JAVA_HOME/bin:$PATH
    

IDE选择

  • IntelliJ IDEA(推荐):功能强大,社区版免费。
  • Eclipse:老牌IDE,适合企业开发。
  • VS Code + Java扩展包:轻量级选择。

验证安装: 打开终端/命令提示符,输入:

java -version
javac -version

如果显示版本信息,说明安装成功。

1.2 第一个Java程序

创建一个名为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        # 运行程序

1.3 基本语法与数据类型

变量与常量

// 变量
int age = 25;           // 整型
double salary = 5000.5; // 浮点型
String name = "张三";   // 字符串
boolean isStudent = true; // 布尔型

// 常量(final关键字)
final double PI = 3.14159;

基本数据类型

类型 大小 范围
byte 1字节 -128~127
short 2字节 -32,768~32,767
int 4字节 -2^31~2^31-1
long 8字节 -2^63~2^63-1
float 4字节 ±3.4e±38
double 8字节 ±1.7e±308
char 2字节 Unicode字符
boolean 1位 true/false

运算符

int a = 10, b = 3;
System.out.println(a + b);  // 13
System.out.println(a % b);  // 1(取模)
System.out.println(a == b); // false(比较)

// 三元运算符
int max = (a > b) ? a : b; // 如果a>b则返回a,否则返回b

1.4 流程控制

条件语句

int score = 85;
if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好");
} else {
    System.out.println("继续努力");
}

循环语句

// for循环
for (int i = 0; i < 5; i++) {
    System.out.println("第" + (i+1) + "次循环");
}

// while循环
int count = 0;
while (count < 3) {
    System.out.println("count: " + count);
    count++;
}

// do-while循环
int num = 0;
do {
    System.out.println("至少执行一次");
    num++;
} while (num < 3);

跳转语句

// break:跳出循环
for (int i = 0; i < 10; i++) {
    if (i == 5) {
        break; // 当i=5时跳出整个循环
    }
    System.out.println(i);
}

// continue:跳过本次循环
for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
        continue; // 跳过偶数
    }
    System.out.println(i); // 只输出奇数
}

第二部分:面向对象编程(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 person1 = new Person("张三", 25);
        Person person2 = new Person("李四", 30);
        
        // 调用方法
        person1.introduce(); // 输出:我叫张三,今年25岁
        person2.introduce(); // 输出:我叫李四,今年30岁
        
        // 使用Getter和Setter
        person1.setAge(26);
        System.out.println(person1.getName() + "现在" + person1.getAge() + "岁");
    }
}

2.2 封装、继承与多态

封装

  • 将数据(属性)和操作数据的方法绑定在一起,隐藏内部实现细节。
  • 通过访问修饰符(private、protected、public)控制访问权限。

继承

// 父类:动物
class Animal {
    public void eat() {
        System.out.println("动物在吃东西");
    }
    
    public void sleep() {
        System.out.println("动物在睡觉");
    }
}

// 子类:狗
class Dog extends Animal {
    public void bark() {
        System.out.println("狗在汪汪叫");
    }
}

// 子类:猫
class Cat extends Animal {
    public void meow() {
        System.out.println("猫在喵喵叫");
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();   // 继承自Animal
        dog.sleep(); // 继承自Animal
        dog.bark();  // Dog自己的方法
        
        Cat cat = new Cat();
        cat.eat();   // 继承自Animal
        cat.meow();  // Cat自己的方法
    }
}

多态

// 多态示例:通过父类引用指向子类对象
public class Main {
    public static void main(String[] args) {
        Animal animal1 = new Dog(); // 父类引用指向子类对象
        Animal animal2 = new Cat(); // 父类引用指向子类对象
        
        animal1.eat(); // 运行时根据实际对象类型调用相应方法
        animal2.eat();
        
        // 向下转型(需要强制类型转换)
        if (animal1 instanceof Dog) {
            Dog dog = (Dog) animal1;
            dog.bark();
        }
    }
}

2.3 抽象类与接口

抽象类

// 抽象类:形状
abstract class Shape {
    // 抽象方法(没有方法体)
    public abstract double area();
    
    // 具体方法
    public void display() {
        System.out.println("这是一个形状");
    }
}

// 具体子类:圆形
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;
    }
}

接口

// 接口:可飞行的
interface Flyable {
    void fly();
}

// 接口:可游泳的
interface Swimmable {
    void swim();
}

// 类实现多个接口
class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("鸭子在飞");
    }
    
    @Override
    public void swim() {
        System.out.println("鸭子在游泳");
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        Duck duck = new Duck();
        duck.fly();
        duck.swim();
    }
}

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

3.1 字符串处理

String类

String str1 = "Hello";
String str2 = "World";
String str3 = str1 + " " + str2; // 字符串拼接

// 常用方法
System.out.println(str3.length()); // 11
System.out.println(str3.charAt(0)); // 'H'
System.out.println(str3.substring(0, 5)); // "Hello"
System.out.println(str3.toUpperCase()); // "HELLO WORLD"
System.out.println(str3.contains("World")); // true

// 字符串比较
String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
System.out.println(s1 == s2); // true(常量池)
System.out.println(s1 == s3); // false(不同对象)
System.out.println(s1.equals(s3)); // true(内容相同)

StringBuilder与StringBuffer

// StringBuilder(非线程安全,性能高)
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString(); // "Hello World"

// StringBuffer(线程安全,性能稍低)
StringBuffer sbf = new StringBuffer();
sbf.append("Hello");
sbf.append(" ");
sbf.append("World");
String result2 = sbf.toString();

3.2 集合框架

List接口

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

// ArrayList(基于动态数组,查询快,增删慢)
List<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Python");
arrayList.add("C++");
System.out.println(arrayList); // [Java, Python, C++]
System.out.println(arrayList.get(1)); // Python

// LinkedList(基于链表,增删快,查询慢)
List<String> linkedList = new LinkedList<>();
linkedList.add("Java");
linkedList.add("Python");
linkedList.add("C++");
linkedList.remove(1); // 删除Python
System.out.println(linkedList); // [Java, C++]

Set接口

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

// HashSet(无序,不重复)
Set<String> set = new HashSet<>();
set.add("Java");
set.add("Python");
set.add("Java"); // 重复元素不会被添加
System.out.println(set); // [Java, Python](顺序不确定)

// 判断元素是否存在
System.out.println(set.contains("Java")); // true

Map接口

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

// HashMap(键值对,键唯一)
Map<String, Integer> map = new HashMap<>();
map.put("Java", 100);
map.put("Python", 90);
map.put("C++", 85);

// 获取值
System.out.println(map.get("Java")); // 100
System.out.println(map.get("Python")); // 90

// 遍历Map
for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

3.3 异常处理

异常类型

  • 检查型异常(Checked Exception):编译时必须处理,如IOException
  • 非检查型异常(Unchecked Exception):运行时异常,如NullPointerException

异常处理语法

try {
    // 可能抛出异常的代码
    int[] arr = new int[5];
    arr[10] = 100; // 会抛出ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
    System.out.println("数组越界:" + e.getMessage());
} catch (Exception e) {
    System.out.println("其他异常:" + e.getMessage());
} finally {
    System.out.println("无论是否异常都会执行");
}

自定义异常

// 自定义检查型异常
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("余额不足,当前余额:" + balance);
        }
        balance -= amount;
    }
}

3.4 泛型

泛型类

// 泛型类
class Box<T> {
    private T content;
    
    public void setContent(T content) {
        this.content = content;
    }
    
    public T getContent() {
        return content;
    }
}

// 使用
public class Main {
    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
    }
}

泛型方法

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

// 使用
public class Main {
    public static void main(String[] args) {
        Integer[] intArray = {1, 2, 3, 4, 5};
        String[] strArray = {"a", "b", "c"};
        
        printArray(intArray); // 1 2 3 4 5
        printArray(strArray); // a b c
    }
}

3.5 多线程

创建线程的两种方式

// 方式1:继承Thread类
class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }
}

// 方式2:实现Runnable接口
class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " - " + i);
        }
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        // 方式1
        MyThread thread1 = new MyThread();
        thread1.start();
        
        // 方式2
        Thread thread2 = new Thread(new MyRunnable());
        thread2.start();
    }
}

线程同步

class Counter {
    private int count = 0;
    
    // 使用synchronized关键字
    public synchronized void increment() {
        count++;
    }
    
    public int getCount() {
        return count;
    }
}

// 使用
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        
        // 创建多个线程同时调用increment
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
        
        t1.start();
        t2.start();
        
        t1.join();
        t2.join();
        
        System.out.println("最终计数:" + counter.getCount()); // 2000
    }
}

第四部分:数据库操作(JDBC)

4.1 JDBC基础

JDBC连接MySQL

import java.sql.*;

public class JDBCDemo {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String username = "root";
        String password = "password";
        
        try {
            // 1. 加载驱动(JDBC 4.0+自动加载)
            Class.forName("com.mysql.cj.jdbc.Driver");
            
            // 2. 建立连接
            Connection conn = DriverManager.getConnection(url, username, password);
            System.out.println("连接成功!");
            
            // 3. 创建Statement
            Statement stmt = conn.createStatement();
            
            // 4. 执行查询
            String sql = "SELECT * FROM users";
            ResultSet rs = stmt.executeQuery(sql);
            
            // 5. 处理结果集
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String email = rs.getString("email");
                System.out.println(id + ", " + name + ", " + email);
            }
            
            // 6. 关闭资源
            rs.close();
            stmt.close();
            conn.close();
            
        } catch (ClassNotFoundException e) {
            System.out.println("找不到驱动类:" + e.getMessage());
        } catch (SQLException e) {
            System.out.println("数据库错误:" + e.getMessage());
        }
    }
}

使用PreparedStatement防止SQL注入

public class PreparedStatementDemo {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String username = "root";
        String password = "password";
        
        try (Connection conn = DriverManager.getConnection(url, username, password)) {
            // 使用try-with-resources自动关闭资源
            
            String sql = "SELECT * FROM users WHERE name = ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            
            // 设置参数
            pstmt.setString(1, "张三");
            
            ResultSet rs = pstmt.executeQuery();
            
            while (rs.next()) {
                System.out.println(rs.getString("email"));
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

4.2 数据库事务

public class TransactionDemo {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String username = "root";
        String password = "password";
        
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, username, password);
            
            // 1. 关闭自动提交
            conn.setAutoCommit(false);
            
            // 2. 执行多个SQL操作
            Statement stmt = conn.createStatement();
            
            // 转账操作
            String sql1 = "UPDATE accounts SET balance = balance - 100 WHERE id = 1";
            String sql2 = "UPDATE accounts SET balance = balance + 100 WHERE id = 2";
            
            stmt.executeUpdate(sql1);
            stmt.executeUpdate(sql2);
            
            // 3. 提交事务
            conn.commit();
            System.out.println("转账成功!");
            
        } catch (SQLException e) {
            // 4. 回滚事务
            if (conn != null) {
                try {
                    conn.rollback();
                    System.out.println("转账失败,已回滚");
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            e.printStackTrace();
        } finally {
            // 5. 关闭连接
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

第五部分:实战项目开发

5.1 项目一:学生管理系统

项目需求

  • 实现学生信息的增删改查
  • 支持按学号、姓名查询
  • 数据持久化到文件或数据库

核心代码示例

import java.io.*;
import java.util.*;

// 学生类
class Student implements Serializable {
    private String id;
    private String name;
    private int age;
    private String major;
    
    public Student(String id, String name, int age, String major) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.major = major;
    }
    
    // Getter和Setter方法...
    
    @Override
    public String toString() {
        return "学号:" + id + ",姓名:" + name + ",年龄:" + age + ",专业:" + major;
    }
}

// 学生管理类
class StudentManager {
    private List<Student> students;
    private String dataFile;
    
    public StudentManager(String dataFile) {
        this.dataFile = dataFile;
        this.students = new ArrayList<>();
        loadData();
    }
    
    // 添加学生
    public void addStudent(Student student) {
        students.add(student);
        saveData();
    }
    
    // 删除学生
    public void deleteStudent(String id) {
        students.removeIf(s -> s.getId().equals(id));
        saveData();
    }
    
    // 查询学生
    public Student findStudent(String id) {
        for (Student s : students) {
            if (s.getId().equals(id)) {
                return s;
            }
        }
        return null;
    }
    
    // 显示所有学生
    public void displayAll() {
        for (Student s : students) {
            System.out.println(s);
        }
    }
    
    // 保存数据到文件
    private void saveData() {
        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream(dataFile))) {
            oos.writeObject(students);
        } catch (IOException e) {
            System.out.println("保存数据失败:" + e.getMessage());
        }
    }
    
    // 从文件加载数据
    @SuppressWarnings("unchecked")
    private void loadData() {
        File file = new File(dataFile);
        if (file.exists()) {
            try (ObjectInputStream ois = new ObjectInputStream(
                    new FileInputStream(dataFile))) {
                students = (List<Student>) ois.readObject();
            } catch (IOException | ClassNotFoundException e) {
                System.out.println("加载数据失败:" + e.getMessage());
            }
        }
    }
}

// 主程序
public class StudentManagementSystem {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        StudentManager manager = new StudentManager("students.dat");
        
        while (true) {
            System.out.println("\n=== 学生管理系统 ===");
            System.out.println("1. 添加学生");
            System.out.println("2. 删除学生");
            System.out.println("3. 查询学生");
            System.out.println("4. 显示所有学生");
            System.out.println("5. 退出");
            System.out.print("请选择操作:");
            
            int choice = scanner.nextInt();
            scanner.nextLine(); // 消耗换行符
            
            switch (choice) {
                case 1:
                    System.out.print("请输入学号:");
                    String id = scanner.nextLine();
                    System.out.print("请输入姓名:");
                    String name = scanner.nextLine();
                    System.out.print("请输入年龄:");
                    int age = scanner.nextInt();
                    scanner.nextLine();
                    System.out.print("请输入专业:");
                    String major = scanner.nextLine();
                    
                    Student student = new Student(id, name, age, major);
                    manager.addStudent(student);
                    System.out.println("添加成功!");
                    break;
                    
                case 2:
                    System.out.print("请输入要删除的学号:");
                    String deleteId = scanner.nextLine();
                    manager.deleteStudent(deleteId);
                    System.out.println("删除成功!");
                    break;
                    
                case 3:
                    System.out.print("请输入要查询的学号:");
                    String queryId = scanner.nextLine();
                    Student found = manager.findStudent(queryId);
                    if (found != null) {
                        System.out.println("查询结果:" + found);
                    } else {
                        System.out.println("未找到该学生!");
                    }
                    break;
                    
                case 4:
                    System.out.println("所有学生信息:");
                    manager.displayAll();
                    break;
                    
                case 5:
                    System.out.println("感谢使用,再见!");
                    scanner.close();
                    return;
                    
                default:
                    System.out.println("无效选择!");
            }
        }
    }
}

5.2 项目二:简易银行系统

项目需求

  • 实现账户创建、存款、取款、转账功能
  • 支持查询余额
  • 使用数据库存储账户信息

核心代码示例

import java.sql.*;
import java.util.Scanner;

// 账户类
class Account {
    private String accountNumber;
    private String accountHolder;
    private double balance;
    
    public Account(String accountNumber, String accountHolder, double balance) {
        this.accountNumber = accountNumber;
        this.accountHolder = accountHolder;
        this.balance = balance;
    }
    
    // Getter和Setter方法...
    
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
    
    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
        }
    }
    
    public double getBalance() {
        return balance;
    }
}

// 银行系统类
class BankSystem {
    private Connection connection;
    
    public BankSystem() {
        try {
            // 连接数据库
            String url = "jdbc:mysql://localhost:3306/bankdb";
            String username = "root";
            String password = "password";
            connection = DriverManager.getConnection(url, username, password);
            
            // 创建表(如果不存在)
            createTable();
        } catch (SQLException e) {
            System.out.println("数据库连接失败:" + e.getMessage());
        }
    }
    
    private void createTable() throws SQLException {
        String sql = "CREATE TABLE IF NOT EXISTS accounts (" +
                     "account_number VARCHAR(20) PRIMARY KEY," +
                     "account_holder VARCHAR(50)," +
                     "balance DECIMAL(10,2))";
        Statement stmt = connection.createStatement();
        stmt.execute(sql);
        stmt.close();
    }
    
    // 创建账户
    public void createAccount(String accountNumber, String accountHolder, double initialBalance) {
        String sql = "INSERT INTO accounts VALUES (?, ?, ?)";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setString(1, accountNumber);
            pstmt.setString(2, accountHolder);
            pstmt.setDouble(3, initialBalance);
            pstmt.executeUpdate();
            System.out.println("账户创建成功!");
        } catch (SQLException e) {
            System.out.println("创建账户失败:" + e.getMessage());
        }
    }
    
    // 存款
    public void deposit(String accountNumber, double amount) {
        String sql = "UPDATE accounts SET balance = balance + ? WHERE account_number = ?";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setDouble(1, amount);
            pstmt.setString(2, accountNumber);
            int rows = pstmt.executeUpdate();
            if (rows > 0) {
                System.out.println("存款成功!");
            } else {
                System.out.println("账户不存在!");
            }
        } catch (SQLException e) {
            System.out.println("存款失败:" + e.getMessage());
        }
    }
    
    // 取款
    public void withdraw(String accountNumber, double amount) {
        // 先检查余额
        double balance = getBalance(accountNumber);
        if (balance < amount) {
            System.out.println("余额不足!");
            return;
        }
        
        String sql = "UPDATE accounts SET balance = balance - ? WHERE account_number = ?";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setDouble(1, amount);
            pstmt.setString(2, accountNumber);
            int rows = pstmt.executeUpdate();
            if (rows > 0) {
                System.out.println("取款成功!");
            } else {
                System.out.println("账户不存在!");
            }
        } catch (SQLException e) {
            System.out.println("取款失败:" + e.getMessage());
        }
    }
    
    // 转账
    public void transfer(String fromAccount, String toAccount, double amount) {
        // 检查源账户余额
        double fromBalance = getBalance(fromAccount);
        if (fromBalance < amount) {
            System.out.println("源账户余额不足!");
            return;
        }
        
        try {
            // 开启事务
            connection.setAutoCommit(false);
            
            // 从源账户扣款
            String sql1 = "UPDATE accounts SET balance = balance - ? WHERE account_number = ?";
            PreparedStatement pstmt1 = connection.prepareStatement(sql1);
            pstmt1.setDouble(1, amount);
            pstmt1.setString(2, fromAccount);
            pstmt1.executeUpdate();
            
            // 向目标账户加款
            String sql2 = "UPDATE accounts SET balance = balance + ? WHERE account_number = ?";
            PreparedStatement pstmt2 = connection.prepareStatement(sql2);
            pstmt2.setDouble(1, amount);
            pstmt2.setString(2, toAccount);
            pstmt2.executeUpdate();
            
            // 提交事务
            connection.commit();
            System.out.println("转账成功!");
            
        } catch (SQLException e) {
            try {
                connection.rollback();
                System.out.println("转账失败,已回滚:" + e.getMessage());
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        } finally {
            try {
                connection.setAutoCommit(true);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    // 查询余额
    public double getBalance(String accountNumber) {
        String sql = "SELECT balance FROM accounts WHERE account_number = ?";
        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
            pstmt.setString(1, accountNumber);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                return rs.getDouble("balance");
            }
        } catch (SQLException e) {
            System.out.println("查询余额失败:" + e.getMessage());
        }
        return -1; // 表示账户不存在
    }
    
    // 关闭数据库连接
    public void close() {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

// 主程序
public class BankSystemDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        BankSystem bank = new BankSystem();
        
        while (true) {
            System.out.println("\n=== 银行系统 ===");
            System.out.println("1. 创建账户");
            System.out.println("2. 存款");
            System.out.println("3. 取款");
            System.out.println("4. 转账");
            System.out.println("5. 查询余额");
            System.out.println("6. 退出");
            System.out.print("请选择操作:");
            
            int choice = scanner.nextInt();
            scanner.nextLine(); // 消耗换行符
            
            switch (choice) {
                case 1:
                    System.out.print("请输入账户号:");
                    String accountNumber = scanner.nextLine();
                    System.out.print("请输入账户持有人:");
                    String accountHolder = scanner.nextLine();
                    System.out.print("请输入初始存款:");
                    double initialBalance = scanner.nextDouble();
                    scanner.nextLine();
                    bank.createAccount(accountNumber, accountHolder, initialBalance);
                    break;
                    
                case 2:
                    System.out.print("请输入账户号:");
                    String depositAccount = scanner.nextLine();
                    System.out.print("请输入存款金额:");
                    double depositAmount = scanner.nextDouble();
                    scanner.nextLine();
                    bank.deposit(depositAccount, depositAmount);
                    break;
                    
                case 3:
                    System.out.print("请输入账户号:");
                    String withdrawAccount = scanner.nextLine();
                    System.out.print("请输入取款金额:");
                    double withdrawAmount = scanner.nextDouble();
                    scanner.nextLine();
                    bank.withdraw(withdrawAccount, withdrawAmount);
                    break;
                    
                case 4:
                    System.out.print("请输入源账户号:");
                    String fromAccount = scanner.nextLine();
                    System.out.print("请输入目标账户号:");
                    String toAccount = scanner.nextLine();
                    System.out.print("请输入转账金额:");
                    double transferAmount = scanner.nextDouble();
                    scanner.nextLine();
                    bank.transfer(fromAccount, toAccount, transferAmount);
                    break;
                    
                case 5:
                    System.out.print("请输入账户号:");
                    String queryAccount = scanner.nextLine();
                    double balance = bank.getBalance(queryAccount);
                    if (balance >= 0) {
                        System.out.println("账户余额:" + balance);
                    } else {
                        System.out.println("账户不存在!");
                    }
                    break;
                    
                case 6:
                    System.out.println("感谢使用,再见!");
                    bank.close();
                    scanner.close();
                    return;
                    
                default:
                    System.out.println("无效选择!");
            }
        }
    }
}

第六部分:进阶学习与资源推荐

6.1 设计模式

单例模式

// 饿汉式单例
class Singleton {
    private static final Singleton instance = new Singleton();
    
    private Singleton() {} // 私有构造方法
    
    public static Singleton getInstance() {
        return instance;
    }
}

// 懒汉式单例(线程安全)
class SingletonLazy {
    private static volatile SingletonLazy instance;
    
    private SingletonLazy() {}
    
    public static SingletonLazy getInstance() {
        if (instance == null) {
            synchronized (SingletonLazy.class) {
                if (instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
}

工厂模式

// 产品接口
interface Shape {
    void draw();
}

// 具体产品
class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("画圆形");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("画矩形");
    }
}

// 工厂类
class ShapeFactory {
    public Shape createShape(String type) {
        if ("circle".equalsIgnoreCase(type)) {
            return new Circle();
        } else if ("rectangle".equalsIgnoreCase(type)) {
            return new Rectangle();
        }
        return null;
    }
}

// 使用
public class Main {
    public static void main(String[] args) {
        ShapeFactory factory = new ShapeFactory();
        Shape circle = factory.createShape("circle");
        circle.draw(); // 画圆形
    }
}

6.2 Java 8+ 新特性

Lambda表达式

// 传统方式
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String s1, String s2) {
        return s1.compareTo(s2);
    }
});

// Lambda表达式
names.sort((s1, s2) -> s1.compareTo(s2));

// 更简洁的写法
names.sort(String::compareTo);

Stream API

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

// 过滤偶数并求和
int sum = numbers.stream()
                .filter(n -> n % 2 == 0)
                .mapToInt(n -> n * 2)
                .sum();
System.out.println(sum); // 120

// 收集结果
List<Integer> evenNumbers = numbers.stream()
                                  .filter(n -> n % 2 == 0)
                                  .collect(Collectors.toList());
System.out.println(evenNumbers); // [2, 4, 6, 8, 10]

Optional类

// 避免NullPointerException
Optional<String> optional = Optional.ofNullable(getValue());

// 如果值存在则执行
optional.ifPresent(value -> System.out.println(value));

// 获取值或默认值
String result = optional.orElse("默认值");

// 如果值不存在则执行
optional.ifPresentOrElse(
    value -> System.out.println("值存在:" + value),
    () -> System.out.println("值不存在")
);

6.3 构建工具与依赖管理

Maven

<!-- pom.xml 示例 -->
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>my-project</artifactId>
    <version>1.0.0</version>
    
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Gradle

// build.gradle 示例
plugins {
    id 'java'
    id 'application'
}

group = 'com.example'
version = '1.0.0'
sourceCompatibility = '17'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'mysql:mysql-connector-java:8.0.33'
    implementation 'org.apache.commons:commons-lang3:3.12.0'
}

application {
    mainClass = 'com.example.Main'
}

6.4 学习资源推荐

在线教程

书籍推荐

  • 《Java核心技术》(Core Java)- Cay S. Horstmann
  • 《Effective Java》- Joshua Bloch
  • 《Java编程思想》- Bruce Eckel

视频课程

  • 尚硅谷Java教程(B站)
  • 黑马程序员Java教程
  • Coursera上的Java专项课程

练习平台

  • LeetCode(算法练习)
  • HackerRank(编程挑战)
  • Codecademy(交互式学习)

第七部分:常见问题与解决方案

7.1 环境配置问题

问题1:找不到或无法加载主类

  • 原因:类名与文件名不一致,或类路径错误。
  • 解决
    1. 确保类名与文件名完全一致(包括大小写)。
    2. 检查编译后的.class文件是否存在。
    3. 使用java -cp . ClassName指定类路径。

问题2:Java版本不兼容

  • 原因:编译和运行的JDK版本不一致。
  • 解决
    1. 使用javac -versionjava -version检查版本。
    2. 确保两者版本一致(推荐JDK 11或17)。

7.2 代码调试技巧

使用IDE调试

  1. 在代码行号左侧点击设置断点。
  2. 右键点击代码选择”Debug”运行。
  3. 使用调试工具栏:
    • Step Over (F8):单步执行,不进入方法内部。
    • Step Into (F7):进入方法内部。
    • Step Out (Shift+F8):跳出当前方法。
    • Resume (F9):继续执行到下一个断点。

打印调试

// 使用System.out.println调试
public void process(int value) {
    System.out.println("开始处理,value=" + value);
    // ... 业务逻辑
    System.out.println("处理完成,结果=" + result);
}

7.3 性能优化建议

避免不必要的对象创建

// 不好的做法
for (int i = 0; i < 1000000; i++) {
    String s = new String("test"); // 每次循环都创建新对象
}

// 好的做法
String s = "test"; // 字符串常量
for (int i = 0; i < 1000000; i++) {
    // 使用已有的字符串对象
}

使用StringBuilder进行字符串拼接

// 不好的做法(创建多个临时字符串)
String result = "";
for (int i = 0; i < 1000; i++) {
    result += i; // 每次拼接都创建新字符串
}

// 好的做法
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

合理使用集合

// 预先指定容量避免扩容
List<String> list = new ArrayList<>(1000); // 预先分配1000个元素的空间

// 选择合适的集合类型
// 需要快速查找:HashMap
// 需要有序:TreeMap
// 需要线程安全:ConcurrentHashMap

第八部分:职业发展建议

8.1 技术栈扩展

Web开发

  • Spring Boot框架
  • RESTful API设计
  • 前端技术(HTML/CSS/JavaScript)

大数据

  • Hadoop生态系统
  • Spark(Java API)
  • 数据仓库技术

移动开发

  • Android开发(Java/Kotlin)
  • Flutter(Dart语言)

8.2 项目经验积累

个人项目

  • 开发一个完整的博客系统
  • 实现一个电商网站后端
  • 构建一个数据分析工具

开源贡献

  • 在GitHub上寻找Java项目
  • 修复bug或添加新功能
  • 参与技术讨论

8.3 面试准备

常见面试题

  1. Java内存模型(JMM)
  2. JVM垃圾回收机制
  3. 多线程与并发编程
  4. 设计模式应用
  5. 数据库优化技巧

算法准备

  • 掌握常见数据结构(数组、链表、树、图)
  • 熟悉排序和查找算法
  • 练习动态规划和回溯算法

结语

Java编程的学习是一个循序渐进的过程,从基础语法到面向对象,再到高级特性和实战项目,每一步都需要扎实的练习和理解。本指南提供了从入门到精通的完整路径,但真正的精通来自于持续的实践和项目经验。

学习建议

  1. 动手实践:每个概念都要通过代码验证
  2. 项目驱动:通过实际项目巩固知识
  3. 持续学习:关注Java新版本和新技术
  4. 社区参与:加入技术社区,与他人交流

记住,编程不是一蹴而就的技能,而是需要长期积累的技艺。保持耐心,享受解决问题的过程,你一定能成为一名优秀的Java开发者!


最后更新:2024年1月
适用版本:Java 11+
难度等级:初级到高级
预计学习时间:3-6个月(每天2小时)