1. Java基础语法概述
Java作为一门面向对象的编程语言,其基础语法构成了整个Java生态的基石。对于初学者而言,掌握这些基础语法就像学习一门新语言的字母和单词一样重要。Java语法借鉴了C/C++的许多特性,但去除了指针等复杂概念,使得它更易于学习和使用。
Java程序的基本结构由类(class)和方法(method)组成。每个Java程序至少包含一个类,而每个类中可以包含多个方法。其中,main方法是程序的入口点,当程序运行时,JVM会首先执行这个方法。一个最简单的Java程序示例如下:
java复制public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
这段代码展示了几个关键语法元素:类定义、方法定义、语句和字符串输出。理解这些基础元素是学习Java的第一步。
提示:Java是严格区分大小写的语言,System.out.println中的大小写必须完全匹配,否则会导致编译错误。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 变量与数据类型
2.1 基本数据类型
Java是一种强类型语言,这意味着每个变量都必须先声明其数据类型才能使用。Java提供了8种基本数据类型:
- 整型:byte(1字节)、short(2字节)、int(4字节)、long(8字节)
- 浮点型:float(4字节)、double(8字节)
- 字符型:char(2字节)
- 布尔型:boolean(1位)
在实际开发中,int和double是最常用的数值类型。对于需要精确计算的场景,如金融领域,建议使用BigDecimal类而非基本浮点类型。
java复制int age = 25;
double price = 19.99;
boolean isStudent = true;
char grade = 'A';
2.2 变量声明与作用域
变量声明的基本语法是:数据类型 变量名 = 初始值;。Java变量有以下几种作用域:
- 类变量(静态变量):使用static修饰,属于类本身
- 实例变量:属于类的实例
- 局部变量:在方法或代码块中定义
java复制public class VariableExample {
static int classVar = 10; // 类变量
int instanceVar = 20; // 实例变量
public void method() {
int localVar = 30; // 局部变量
System.out.println(localVar);
}
}
注意:局部变量必须在使用前初始化,而实例变量和类变量会有默认值(如int为0,对象为null)。
3. 运算符与表达式
3.1 算术运算符
Java支持标准的算术运算符:+、-、*、/、%。特别需要注意的是整数除法会截断小数部分:
java复制int a = 5 / 2; // 结果是2,不是2.5
double b = 5.0 / 2; // 结果是2.5
3.2 关系与逻辑运算符
关系运算符(>、<、==、!=等)用于比较值,返回boolean结果。逻辑运算符(&&、||、!)用于组合多个boolean表达式:
java复制int x = 10, y = 20;
boolean result = (x < y) && (y != 0); // true
3.3 位运算符与三元运算符
位运算符(&、|、^、~、<<、>>、>>>)直接操作整数的二进制位。三元运算符(?:)提供简洁的条件表达式:
java复制int a = 10, b = 20;
int max = (a > b) ? a : b; // 返回较大的值
4. 控制流程语句
4.1 条件语句
if-else语句是基本的条件控制结构。对于多条件判断,switch-case语句更为清晰:
java复制int day = 3;
switch(day) {
case 1: System.out.println("Monday"); break;
case 2: System.out.println("Tuesday"); break;
// ...其他case
default: System.out.println("Invalid day");
}
提示:从Java 7开始,switch支持String类型,但要注意case的字符串是区分大小写的。
4.2 循环结构
Java提供了三种循环结构:for、while和do-while。for循环特别适合已知迭代次数的情况:
java复制// 打印1到10
for(int i=1; i<=10; i++) {
System.out.println(i);
}
// while循环示例
int j = 1;
while(j <= 10) {
System.out.println(j);
j++;
}
4.3 跳转语句
break用于退出循环或switch,continue跳过当前迭代,return从方法返回:
java复制for(int i=0; i<10; i++) {
if(i == 5) break; // 当i等于5时退出循环
if(i % 2 == 0) continue; // 跳过偶数
System.out.println(i);
}
5. 数组与字符串
5.1 数组基础
数组是存储固定大小同类型元素的容器。Java数组是对象,需要先声明再初始化:
java复制// 声明并初始化数组
int[] numbers = new int[5]; // 5个元素的整型数组
int[] primes = {2, 3, 5, 7, 11}; // 直接初始化
// 访问数组元素
System.out.println(primes[0]); // 输出2
注意:数组索引从0开始,访问越界会抛出ArrayIndexOutOfBoundsException。
5.2 多维数组
Java支持多维数组,最常见的是二维数组:
java复制int[][] matrix = new int[3][3]; // 3x3矩阵
matrix[0][0] = 1; // 第一行第一列赋值为1
// 不规则数组
int[][] irregular = new int[3][];
irregular[0] = new int[2];
irregular[1] = new int[3];
5.3 字符串处理
String是Java中最常用的类之一,提供了丰富的字符串操作方法:
java复制String str = "Hello";
System.out.println(str.length()); // 5
System.out.println(str.concat(" World")); // "Hello World"
System.out.println(str.substring(1, 3)); // "el"
提示:String对象是不可变的,任何修改操作都会创建新的String对象。频繁字符串拼接应使用StringBuilder。
6. 方法与参数传递
6.1 方法定义与调用
方法是执行特定任务的代码块。定义方法时需要指定返回类型、方法名和参数列表:
java复制public int add(int a, int b) {
return a + b;
}
// 方法调用
int sum = add(5, 3); // sum = 8
6.2 参数传递机制
Java采用值传递:基本类型传递值副本,对象类型传递引用副本。这意味着方法内修改对象参数会影响原始对象:
java复制public void modifyArray(int[] arr) {
arr[0] = 100; // 会修改原始数组
}
int[] myArray = {1, 2, 3};
modifyArray(myArray);
System.out.println(myArray[0]); // 输出100
6.3 方法重载
方法重载允许同一类中有多个同名方法,只要参数列表不同:
java复制public int add(int a, int b) { return a + b; }
public double add(double a, double b) { return a + b; }
public int add(int a, int b, int c) { return a + b + c; }
7. 异常处理基础
7.1 异常类型
Java异常分为检查型异常(必须处理)和非检查型异常(运行时异常)。常见运行时异常包括:
- NullPointerException:空指针引用
- ArrayIndexOutOfBoundsException:数组越界
- ClassCastException:类型转换错误
7.2 try-catch-finally
基本的异常处理结构:
java复制try {
// 可能抛出异常的代码
int result = 10 / 0;
} catch (ArithmeticException e) {
// 处理特定异常
System.out.println("除零错误");
} finally {
// 无论是否发生异常都会执行
System.out.println("清理资源");
}
7.3 自定义异常
可以通过继承Exception或RuntimeException创建自定义异常:
java复制class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
// 使用自定义异常
throw new MyException("自定义错误信息");
8. 面向对象基础
8.1 类与对象
类是对象的蓝图,对象是类的实例。定义类的基本语法:
java复制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 + "岁");
}
}
// 创建对象
Person p = new Person("张三", 25);
p.introduce();
8.2 封装与访问控制
Java通过访问修饰符实现封装:
- private:仅本类可见
- protected:本类、子类和同包类可见
- public:所有类可见
- 默认(无修饰符):同包类可见
良好的封装实践是将字段设为private,通过public方法访问:
java复制public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
if(name != null && !name.isEmpty()) {
this.name = name;
}
}
}
8.3 继承与多态
继承使用extends关键字,子类继承父类的非private成员。方法重写是实现多态的关键:
java复制class Animal {
public void sound() {
System.out.println("动物发出声音");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("汪汪汪");
}
}
// 多态示例
Animal myDog = new Dog();
myDog.sound(); // 输出"汪汪汪"
9. 常用工具类
9.1 包装类
Java为每个基本类型提供了对应的包装类,如Integer、Double等。自动装箱和拆箱简化了基本类型与包装类的转换:
java复制Integer num = 10; // 自动装箱
int value = num; // 自动拆箱
9.2 Math与Random
Math类提供常用数学运算,Random类用于生成随机数:
java复制double root = Math.sqrt(25); // 5.0
double power = Math.pow(2, 3); // 8.0
Random rand = new Random();
int randomNum = rand.nextInt(100); // 0-99的随机数
9.3 日期时间API
Java 8引入了新的日期时间API(java.time包),解决了旧API的诸多问题:
java复制LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
String formatted = now.format(formatter);
10. 集合框架基础
10.1 List接口
List是有序集合,允许重复元素。常用实现类有ArrayList和LinkedList:
java复制List<String> names = new ArrayList<>();
names.add("Alice");
names.add("Bob");
names.add("Alice"); // 允许重复
System.out.println(names.get(0)); // "Alice"
System.out.println(names.size()); // 3
10.2 Set接口
Set是不允许重复元素的集合。常用实现类有HashSet和TreeSet:
java复制Set<Integer> numbers = new HashSet<>();
numbers.add(1);
numbers.add(2);
numbers.add(1); // 重复元素不会被添加
System.out.println(numbers.size()); // 2
10.3 Map接口
Map存储键值对,键不能重复。常用实现类有HashMap和TreeMap:
java复制Map<String, Integer> ageMap = new HashMap<>();
ageMap.put("Alice", 25);
ageMap.put("Bob", 30);
System.out.println(ageMap.get("Alice")); // 25
11. 输入输出基础
11.1 控制台输入输出
使用System.out输出,Scanner类读取控制台输入:
java复制Scanner scanner = new Scanner(System.in);
System.out.print("请输入你的名字: ");
String name = scanner.nextLine();
System.out.println("你好, " + name);
scanner.close();
11.2 文件读写
使用FileReader/FileWriter进行文本文件读写:
java复制// 写入文件
try (FileWriter writer = new FileWriter("test.txt")) {
writer.write("Hello, File!");
}
// 读取文件
try (FileReader reader = new FileReader("test.txt")) {
int ch;
while ((ch = reader.read()) != -1) {
System.out.print((char)ch);
}
}
11.3 序列化与反序列化
Java对象可以通过实现Serializable接口支持序列化:
java复制class Student implements Serializable {
private String name;
// 其他字段和方法
}
// 序列化对象到文件
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.dat"))) {
oos.writeObject(new Student("Alice"));
}
// 从文件反序列化对象
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("student.dat"))) {
Student s = (Student) ois.readObject();
System.out.println(s.getName());
}
12. 泛型基础
12.1 泛型类与接口
泛型提供了编译时类型安全检查,避免了运行时类型转换:
java复制class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
// 使用泛型类
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String value = stringBox.getContent(); // 不需要类型转换
12.2 泛型方法
方法也可以定义为泛型方法,独立于类的泛型参数:
java复制public <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
// 调用泛型方法
Integer[] intArray = {1, 2, 3};
String[] strArray = {"A", "B", "C"};
printArray(intArray);
printArray(strArray);
12.3 类型通配符
通配符(?)提供了更灵活的泛型使用方式:
java复制public void processList(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num.doubleValue());
}
}
// 可以接受List<Integer>, List<Double>等
processList(Arrays.asList(1, 2, 3));
processList(Arrays.asList(1.1, 2.2, 3.3));
13. 枚举与注解
13.1 枚举类型
枚举是一种特殊的类,表示一组常量:
java复制enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
// 使用枚举
Day today = Day.MONDAY;
if (today == Day.MONDAY) {
System.out.println("今天是周一");
}
13.2 注解基础
注解(Annotation)为代码添加元数据,不影响程序逻辑:
java复制@Override // 标记方法重写
public String toString() {
return "Annotation example";
}
@Deprecated // 标记过时方法
public void oldMethod() {
// ...
}
13.3 自定义注解
可以定义自己的注解类型:
java复制@interface Author {
String name();
String date();
int version() default 1;
}
@Author(name = "John", date = "2023-01-01", version = 2)
public class MyClass {
// ...
}
14. Lambda表达式与函数式接口
14.1 函数式接口
函数式接口是只包含一个抽象方法的接口,可以用@FunctionalInterface注解标记:
java复制@FunctionalInterface
interface Greeting {
void sayHello(String name);
}
// 使用匿名类实现
Greeting greet = new Greeting() {
@Override
public void sayHello(String name) {
System.out.println("Hello, " + name);
}
};
greet.sayHello("Alice");
14.2 Lambda表达式
Lambda表达式简化了函数式接口的实现:
java复制Greeting greetLambda = name -> System.out.println("Hello, " + name);
greetLambda.sayHello("Bob");
14.3 方法引用
方法引用是Lambda的简写形式,有四种类型:
java复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(System.out::println); // 实例方法引用
15. 流式API基础
15.1 创建流
Java 8 Stream API提供了强大的数据处理能力:
java复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Stream<String> stream = names.stream(); // 从集合创建流
Stream<Integer> numbers = Stream.of(1, 2, 3); // 直接创建流
15.2 中间操作
中间操作可以对流进行转换,返回新的流:
java复制names.stream()
.filter(name -> name.length() > 3) // 过滤
.map(String::toUpperCase) // 映射
.sorted() // 排序
.forEach(System.out::println); // 终端操作
15.3 终端操作
终端操作会触发流的处理并返回结果:
java复制long count = names.stream().count(); // 计数
Optional<String> first = names.stream().findFirst(); // 获取第一个
List<String> result = names.stream().collect(Collectors.toList()); // 收集为列表
16. 多线程基础
16.1 线程创建
创建线程有两种基本方式:继承Thread类或实现Runnable接口:
java复制// 方式1:继承Thread
class MyThread extends Thread {
public void run() {
System.out.println("线程运行中");
}
}
// 方式2:实现Runnable
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable运行中");
}
}
// 启动线程
new MyThread().start();
new Thread(new MyRunnable()).start();
16.2 线程同步
当多个线程访问共享资源时,需要使用同步机制:
java复制class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
16.3 线程池
使用线程池可以高效管理线程资源:
java复制ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executor.execute(() -> {
System.out.println(Thread.currentThread().getName() + " 执行任务");
});
}
executor.shutdown();
17. 反射机制基础
17.1 获取Class对象
反射允许程序在运行时检查类和对象的信息:
java复制Class<?> clazz1 = String.class; // 通过类字面量
Class<?> clazz2 = Class.forName("java.lang.String"); // 通过全限定名
Class<?> clazz3 = "Hello".getClass(); // 通过对象实例
17.2 访问字段和方法
通过反射可以动态访问类的成员:
java复制Class<?> clazz = Person.class;
Field[] fields = clazz.getDeclaredFields(); // 获取所有字段
Method[] methods = clazz.getDeclaredMethods(); // 获取所有方法
// 访问私有字段
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true);
Person p = new Person("Alice", 25);
String nameValue = (String) nameField.get(p);
17.3 动态创建对象
反射可以动态创建对象和调用方法:
java复制Class<?> clazz = Class.forName("com.example.Person");
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object instance = constructor.newInstance("Bob", 30);
Method method = clazz.getMethod("introduce");
method.invoke(instance);
18. 网络编程基础
18.1 Socket编程
基本的客户端-服务器通信模型:
java复制// 服务器端
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket = serverSocket.accept(); // 等待客户端连接
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = in.readLine();
System.out.println("收到消息: " + message);
socket.close();
// 客户端
Socket clientSocket = new Socket("localhost", 8080);
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
out.println("Hello, Server!");
clientSocket.close();
18.2 URL处理
Java提供了URL类来处理URL连接:
java复制URL url = new URL("https://www.example.com");
URLConnection connection = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
18.3 HTTP客户端
Java 11引入了新的HttpClient API:
java复制HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://www.example.com"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
19. 数据库连接基础
19.1 JDBC基础
Java通过JDBC API连接数据库的基本步骤:
java复制// 1. 加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 建立连接
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
Connection conn = DriverManager.getConnection(url, user, password);
// 3. 创建Statement
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
// 4. 处理结果
while (rs.next()) {
System.out.println(rs.getString("username"));
}
// 5. 关闭资源
rs.close();
stmt.close();
conn.close();
19.2 PreparedStatement
PreparedStatement可以防止SQL注入并提高性能:
java复制String sql = "INSERT INTO users (username, password) VALUES (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "alice");
pstmt.setString(2, "secret");
pstmt.executeUpdate();
19.3 事务处理
JDBC支持事务管理:
java复制try {
conn.setAutoCommit(false); // 开始事务
// 执行多个SQL操作
stmt.executeUpdate("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
stmt.executeUpdate("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
conn.commit(); // 提交事务
} catch (SQLException e) {
conn.rollback(); // 回滚事务
}
20. 单元测试基础
20.1 JUnit基础
JUnit是Java最常用的单元测试框架:
java复制import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
void testAdd() {
Calculator calc = new Calculator();
assertEquals(5, calc.add(2, 3));
}
@Test
void testDivide() {
Calculator calc = new Calculator();
assertThrows(ArithmeticException.class, () -> calc.divide(10, 0));
}
}
20.2 测试生命周期
JUnit提供了测试生命周期注解:
java复制@BeforeEach
void setUp() {
// 每个测试方法前执行
}
@AfterEach
void tearDown() {
// 每个测试方法后执行
}
@BeforeAll
static void initAll() {
// 所有测试前执行一次
}
@AfterAll
static void tearDownAll() {
// 所有测试后执行一次
}
20.3 参数化测试
JUnit支持参数化测试,可以多次运行同一测试方法:
java复制@ParameterizedTest
@ValueSource(ints = {1, 3, 5, -3, 15})
void testIsOdd(int number) {
assertTrue(Calculator.isOdd(number));
}
21. 日志记录基础
21.1 Log4j配置
Log4j是常用的日志框架,基本配置如下:
properties复制# log4j2.properties
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = STDOUT
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
21.2 日志记录实践
在代码中使用Log4j记录日志:
java复制import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyClass {
private static final Logger logger = LogManager.getLogger(MyClass.class);
public void doSomething() {
logger.debug("调试信息");
logger.info("一般信息");
logger.warn("警告信息");
logger.error("错误信息", new Exception("示例异常"));
}
}
21.3 日志级别与最佳实践
Log4j定义了以下日志级别(从低到高):
- TRACE:最详细的日志信息
- DEBUG:调试信息
- INFO:一般信息
- WARN:潜在问题
- ERROR:错误事件
- FATAL:严重错误
日志记录的最佳实践包括:
- 合理选择日志级别
- 记录有意义的上下文信息
- 避免在循环中记录日志
- 使用参数化日志消息
22. 构建工具基础
22.1 Maven基础
Maven是Java项目的主流构建工具,核心配置文件pom.xml:
xml复制<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
常用Maven命令:
- mvn compile:编译项目
- mvn test:运行测试
- mvn package:打包项目
- mvn install:安装到本地仓库
22.2 Gradle基础
Gradle是另一个流行的构建工具,使用Groovy DSL配置:
groovy复制plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
testImplementation 'junit:junit:4.12'
}
常用Gradle命令:
- gradle build:构建项目
- gradle test:运行测试
- gradle run:运行应用
22.3 依赖管理
构建工具的核心功能是依赖管理,可以自动下载和解决依赖冲突:
xml复制<!-- Maven排除传递依赖 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>org.unwanted</groupId>
<artifactId>dependency</artifactId>
</exclusion>
</exclusions>
</dependency>
23. Java新特性概览
23.1 Java 8新特性
Java 8引入了许多重要特性:
- Lambda表达式
- 流式API
- 默认方法
- 新的日期时间API
- Optional类
java复制// Optional示例
Optional<String> optional = Optional.ofNullable(getName());
String name = optional.orElse("default");
23.2 Java 11新特性
Java 11是长期支持(LTS)版本,主要特性:
- 局部变量类型推断(var)
- 新的HTTP客户端
- 单文件源代码程序
- String新增方法
java复制// var示例
var list = new ArrayList<String>(); // 推断为ArrayList<String>
23.3 Java 17新特性
最新的LTS版本Java 17特性:
- 密封类(sealed class)
- 模式匹配instanceof
- 文本块改进
- 新的随机数生成器API
java复制// 密封类示例
public sealed class Shape permits Circle, Square, Rectangle {
// ...
}
public final class Circle extends Shape {
// ...
}
24. 性能优化基础
24.1 JVM内存模型
理解JVM内存模型对性能优化至关重要:
- 堆(Heap):对象实例
- 栈(Stack):局部变量和方法调用
- 方法区(Method Area):类信息
- 程序计数器(PC Register)
- 本地方法栈(Native Method Stack)
24.2 垃圾回收基础
Java的自动内存管理通过垃圾回收实现,主要GC算法:
- 标记-清除
- 复制
- 标记-整理
- 分代收集
常见的垃圾收集器:
- Serial GC
- Parallel GC
- CMS
- G1
- ZGC
24.3 性能调优实践
基本的性能优化建议:
- 避免创建不必要的对象
- 使用StringBuilder处理字符串拼接
- 合理选择集合类型
- 使用缓存减少重复计算
- 并行处理适合的任务
java复制// 使用StringBuilder替代字符串拼接
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {
sb.append(i).append(", ");
}
String result = sb.toString();
25. 设计模式基础
25.1 单例模式
确保一个类只有一个实例:
java复制public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
25.2 工厂模式
创建对象的接口,让子类决定实例化哪个类:
java复制interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() {
System.out.println("画圆");
}
}
class ShapeFactory {
public Shape getShape(String type) {
if ("circle".equals(type)) {
return new Circle();
}
return null;
}
}
25.3 观察者模式
定义对象间的一对多依赖,当一个对象改变状态时,所有依赖者都会收到通知:
java复制interface Observer {
void update(String message);
}
class ConcreteObserver implements Observer {
public void update(String message) {
System.out.println("收到消息: " + message);
}
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer o) {
observers.add(o);
}
public void notifyObservers(String message) {
for (Observer o : observers) {
o.update(message);
}
}
}
26. 安全编程基础
26.1 输入验证
防止恶意输入的安全措施:
java复制public boolean isValidUsername(String username) {
// 只允许字母数字和下划线,长度3-20
return username != null && username.matches("^[a-zA-Z0-9_]{3,20}$");
}
26.2 密码安全
安全处理用户密码:
java复制import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
public class PasswordUtil {
public static String generateSalt() {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
return Base64.getEncoder().encodeToString(salt);
}
public static String hashPassword(String password, String salt) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(Base64.getDecoder().decode(salt));
byte[] hashedPassword = md.digest(password.getBytes());
return Base64.getEncoder().encodeToString(hashedPassword);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
26.3 SQL注入防护
使用PreparedStatement防止SQL注入:
java复制// 不安全的写法
String query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
// 安全的写法
String query = "SELECT * FROM users WHERE username = ? AND password = ?";
PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setString(1, username);
pstmt.setString(2, password);
ResultSet rs = pstmt.executeQuery();
27. 国际化与本地化
27.1 资源包
使用ResourceBundle管理多语言资源:
properties复制# messages_en.properties
greeting=Hello
farewell=Goodbye
# messages_zh.properties
greeting=你好
farewell=再见
java复制Locale locale = Locale.getDefault(); // 或 new Locale("zh", "CN")
ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);
String greeting = bundle.getString("greeting");
27.2 日期与数字格式化
根据地区格式化日期和数字:
java复制Locale locale = new Locale("zh", "CN");
NumberFormat nf = NumberFormat.getNumberInstance(locale);
String formattedNumber = nf.format(1234567.89); // "1,234,567.89"或"1.234.567,89"
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, locale);
String formattedDate = df.format(new Date()); // "2023年1月1日"或"January 1, 2023"
27.3 字符编码处理
正确处理不同字符编码:
java复制// 读取UTF-8文件
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream("file.txt"), StandardCharsets.UTF_8));
// 写入GBK文件
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream("file.txt"), "GBK"));
28. Java模块系统
28.1 模块基础
Java 9引入了模块系统,module-info.java定义模块:
java复制module com.example.myapp {
requires java.base; // 隐式依赖
requires java.sql;
requires transitive com.example.lib; // 传递依赖
exports com.example.myapp.api;
opens com.example.myapp.internal to com.example.test
