1. Java面向对象编程基础:类语法全解析
第一次接触Java面向对象编程时,我被"类"这个概念困扰了很久。直到在项目中真正开始设计用户管理系统,把User类、Order类这些业务实体用代码具象化,才突然明白为什么说"万物皆对象"。今天我们就从最基础的类语法开始,用实际案例拆解Java类的核心要素。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 类的基本结构剖析
2.1 类声明与命名规范
每个Java类都始于class关键字,规范的类名应该:
- 使用大驼峰命名法(如EmployeeSalary)
- 避免数字开头
- 与文件名严格一致(Employee.java对应public class Employee)
java复制// 电商系统中的典型类声明
public class Product {
// 类体内容
}
注意:一个.java文件可以有多个类,但public类只能有一个且必须与文件名相同
2.2 成员变量设计原则
字段(Field)是类的状态载体,设计时需要考虑:
- 访问控制:优先private保护数据
- 数据类型:根据业务选择最精确的类型
- 命名规范:小驼峰命名(如productName)
java复制public class BankAccount {
private String accountNumber; // 账户编号
private double balance; // 余额
private Date openDate; // 开户日期
}
2.3 方法设计的黄金法则
方法体现对象的行为能力,建议:
- 单一职责原则(一个方法只做一件事)
- 动词开头命名(如calculateTax())
- 控制参数数量(不超过5个)
java复制public class Calculator {
// 典型的方法结构
public double add(double num1, double num2) {
return num1 + num2;
}
// 带访问控制的方法
private boolean validateInput(double input) {
return !Double.isNaN(input);
}
}
3. 构造方法深度解析
3.1 默认构造方法的陷阱
当类没有显式定义构造方法时,Java会提供默认无参构造器。但一旦定义了任何构造方法,默认构造器就不再自动生成。这个特性常导致继承问题:
java复制public class Parent {
public Parent(int id) { /*...*/ }
}
public class Child extends Parent {
// 编译错误!需要显式调用父类构造器
public Child() {
super(0); // 必须添加这行
}
}
3.2 构造方法重载实践
通过构造方法重载实现多种初始化方式:
java复制public class Employee {
private String name;
private int age;
// 全参构造器
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
// 只初始化name的构造器
public Employee(String name) {
this(name, 18); // 调用全参构造器
}
}
技巧:使用this()调用同类构造器时,必须作为第一条语句
4. static关键字的正确打开方式
4.1 静态字段的内存原理
静态字段属于类而非实例,所有对象共享同一内存空间。比如电商系统中的订单计数器:
java复制public class Order {
private static int count = 0; // 记录创建的订单数
public Order() {
count++;
}
public static int getCount() {
return count;
}
}
4.2 静态方法使用场景
适合工具类方法的实现,比如数学计算工具:
java复制public class MathUtils {
public static double circleArea(double radius) {
return Math.PI * radius * radius;
}
// 调用方式:MathUtils.circleArea(5.0)
}
警告:静态方法中不能直接访问非静态成员,这会导致编译错误
5. 包管理与访问控制
5.1 包声明的最佳实践
包名应该:
- 全部小写
- 使用公司域名倒序(如com.example.project)
- 反映功能模块划分
java复制package com.ecommerce.entity;
public class Product {
//...
}
5.2 访问修饰符实战指南
四种访问级别对比:
| 修饰符 | 类内 | 同包 | 子类 | 任意位置 |
|---|---|---|---|---|
| private | √ | × | × | × |
| (default) | √ | √ | × | × |
| protected | √ | √ | √ | × |
| public | √ | √ | √ | √ |
典型应用场景:
- private:字段封装
- protected:模板方法模式
- public:API接口
6. 类设计常见陷阱与解决方案
6.1 可变性风险控制
以下代码存在安全隐患:
java复制public class User {
public List<String> permissions;
// 调用者可能直接修改内部集合
// user.permissions.add("ADMIN");
}
修正方案:
java复制public class User {
private List<String> permissions = new ArrayList<>();
// 返回不可修改的视图
public List<String> getPermissions() {
return Collections.unmodifiableList(permissions);
}
}
6.2 equals和hashCode契约
重写equals时必须同时重写hashCode:
java复制public class Student {
private String id;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
return id.equals(((Student)o).id);
}
@Override
public int hashCode() {
return id.hashCode();
}
}
7. 高级类特性入门
7.1 初始化块的执行顺序
实例初始化顺序示例:
java复制public class InitDemo {
private static String staticField = initStaticField();
static {
System.out.println("静态初始化块");
}
private String instanceField = initInstanceField();
{
System.out.println("实例初始化块");
}
// 构造器最后执行
public InitDemo() {
System.out.println("构造器");
}
private static String initStaticField() {
System.out.println("静态字段初始化");
return "value";
}
private String initInstanceField() {
System.out.println("实例字段初始化");
return "value";
}
}
输出顺序:
- 静态字段初始化
- 静态初始化块
- 实例字段初始化
- 实例初始化块
- 构造器
7.2 内部类的四种形态
- 成员内部类:作为外部类的成员
- 局部内部类:方法内定义的类
- 匿名内部类:没有类名的即时实现
- 静态内部类:static修饰的嵌套类
典型应用案例:
java复制// 静态内部类实现单例模式
public class Singleton {
private Singleton() {}
private static class Holder {
static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
8. 类加载机制揭秘
8.1 类加载的三大阶段
- 加载:查找并加载字节码
- 链接:验证、准备、解析
- 初始化:执行静态初始化
8.2 类初始化触发条件
以下情况会触发类初始化:
- 创建实例(new)
- 访问静态字段/方法(非final)
- Class.forName()反射调用
- 主类(包含main方法的类)
特别注意:final静态常量(编译期常量)不会触发初始化
java复制public class ClassLoadDemo {
static {
System.out.println("类初始化");
}
public static final String CONSTANT = "VALUE"; // 不会触发初始化
public static String variable = "VALUE"; // 会触发初始化
}
9. 实战:设计一个完整的用户类
综合应用所有知识点:
java复制package com.example.system.model;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
/**
* 用户实体类
*/
public class User {
// 静态字段
private static int nextId = 1;
// 实例字段
private final int id;
private String username;
private String password;
private LocalDate registerDate;
private List<String> roles;
// 构造方法
public User(String username, String password) {
this.id = nextId++;
this.username = username;
this.password = encrypt(password);
this.registerDate = LocalDate.now();
this.roles = Collections.singletonList("GUEST");
}
// 静态工具方法
private static String encrypt(String plainText) {
// 实际项目应使用BCrypt等加密库
return "ENCRYPTED_" + plainText.hashCode();
}
// 实例方法
public boolean hasRole(String role) {
return roles.contains(role);
}
// Getter/Setter
public int getId() { return id; }
public String getUsername() { return username; }
// 防止密码被意外修改
public void setPassword(String newPassword) {
this.password = encrypt(newPassword);
}
// 防御性拷贝
public List<String> getRoles() {
return Collections.unmodifiableList(roles);
}
// 重写重要方法
@Override
public String toString() {
return "User#" + id + "[" + username + "]";
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
return id == ((User)o).id;
}
@Override
public int hashCode() {
return id;
}
}
10. 类设计进阶技巧
10.1 不可变类设计模式
创建后状态不可改变的类,具有线程安全等优势:
java复制public final class ImmutablePoint {
private final double x;
private final double y;
public ImmutablePoint(double x, double y) {
this.x = x;
this.y = y;
}
// 只有getter没有setter
public double getX() { return x; }
public double getY() { return y; }
// 返回新对象而非修改现有对象
public ImmutablePoint move(double dx, double dy) {
return new ImmutablePoint(x + dx, y + dy);
}
}
10.2 Builder模式解决构造参数过多
当构造参数超过4个时建议使用:
java复制public class Computer {
private final String cpu;
private final String gpu;
// 更多字段...
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.gpu = builder.gpu;
//...
}
public static class Builder {
private String cpu;
private String gpu;
//...
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
// 使用方式
Computer pc = new Computer.Builder()
.cpu("i7")
.gpu("RTX3080")
.build();
11. 常见问题排查手册
11.1 编译错误:无法从静态上下文中引用非静态变量
问题代码:
java复制public class Test {
private int value;
public static void main(String[] args) {
System.out.println(value); // 编译错误
}
}
解决方案:
- 将字段改为static
- 或者通过对象实例访问
11.2 空指针异常:未初始化对象
问题代码:
java复制public class UserService {
private UserRepository repository; // 未初始化
public void save(User user) {
repository.save(user); // NullPointerException
}
}
解决方案:
- 依赖注入
- 构造器初始化
- 懒加载+判空
11.3 继承中的构造器链问题
问题代码:
java复制public class Parent {
public Parent(int id) {}
}
public class Child extends Parent {
public Child() {} // 编译错误
}
修正方案:
java复制public class Child extends Parent {
public Child() {
super(0); // 显式调用父类构造器
}
}
12. 性能优化小贴士
-
减少类加载开销:
- 避免过度使用静态块
- 延迟加载重量级资源
-
对象复用策略:
- 对不可变对象使用享元模式
- 考虑对象池技术
-
内存占用优化:
- 对大量小对象考虑扁平化结构
- 注意内部类对外部类的隐式引用
-
方法调用优化:
- 将高频访问方法设为final
- 小方法更利于JIT内联
java复制// 优化后的向量类示例
public final class OptimizedVector {
private final float[] components;
// 避免创建多个迭代器对象
public void forEach(Consumer<Float> action) {
for (float c : components) {
action.accept(c);
}
}
// 方法设为final便于内联
public final int size() {
return components.length;
}
}
13. 现代Java类特性前瞻
13.1 record类(Java14+)
简化不可变类的声明:
java复制// 传统方式
public final class Point {
private final double x;
private final double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
// getters, equals, hashCode, toString...
}
// Record方式
public record Point(double x, double y) {
// 自动生成所有样板代码
}
13.2 sealed类(Java17+)
限制类的继承范围:
java复制public sealed class Shape
permits Circle, Square, Rectangle {
// 基类定义
}
public final class Circle extends Shape {
private double radius;
}
public non-sealed class Square extends Shape {
private double side;
}
14. 工具类设计规范
14.1 通用工具类模板
java复制public final class StringUtils {
// 防止实例化
private StringUtils() {
throw new AssertionError();
}
public static boolean isBlank(String str) {
return str == null || str.trim().isEmpty();
}
public static String capitalize(String str) {
if (isBlank(str)) return str;
return str.substring(0, 1).toUpperCase()
+ str.substring(1);
}
}
14.2 使用注意事项
- 所有方法应该是静态的
- 类应该是final且有无参private构造器
- 方法应该处理null输入(防御性编程)
- 避免工具类之间的循环依赖
15. 领域建模实战案例
电商系统核心类设计:
java复制// 值对象
public record Money(BigDecimal amount, Currency currency) {
public Money add(Money other) {
if (!currency.equals(other.currency)) {
throw new IllegalArgumentException("Currency mismatch");
}
return new Money(amount.add(other.amount), currency);
}
}
// 实体类
public class Product {
private Long id;
private String name;
private Money price;
private int stock;
// 领域方法
public void reduceStock(int quantity) {
if (quantity <= 0) throw new IllegalArgumentException();
if (stock < quantity) throw new IllegalStateException();
stock -= quantity;
}
}
// 聚合根
public class Order {
private Long id;
private List<OrderItem> items;
private OrderStatus status;
public void addItem(Product product, int quantity) {
items.add(new OrderItem(product, quantity));
}
public void submit() {
if (status != OrderStatus.DRAFT) {
throw new IllegalStateException();
}
status = OrderStatus.SUBMITTED;
items.forEach(item ->
item.getProduct().reduceStock(item.getQuantity()));
}
}
16. 单元测试中的类技巧
16.1 测试工具类示例
java复制class StringUtilsTest {
@Test
void isBlank_ShouldReturnTrueForNullInput() {
assertTrue(StringUtils.isBlank(null));
}
@ParameterizedTest
@ValueSource(strings = {"", " ", "\t", "\n"})
void isBlank_ShouldReturnTrueForBlankStrings(String input) {
assertTrue(StringUtils.isBlank(input));
}
}
16.2 测试替身使用策略
| 替身类型 | 适用场景 | 实现方式 |
|---|---|---|
| Dummy | 需要但不使用的参数 | 简单空对象 |
| Stub | 返回预设值 | 硬编码返回值 |
| Mock | 验证交互行为 | Mockito等框架 |
| Spy | 部分方法真实调用 | 包装真实对象 |
| Fake | 轻量级功能实现 | 简化版真实实现 |
java复制// Mock示例
@Test
void shouldSendEmailWhenOrderSubmitted() {
// 准备
EmailService mockEmail = mock(EmailService.class);
Order order = new Order(mockEmail);
// 执行
order.submit();
// 验证
verify(mockEmail).sendConfirmation(any());
}
17. 设计模式中的类应用
17.1 策略模式实现
java复制// 策略接口
public interface DiscountStrategy {
Money apply(Money original);
}
// 具体策略
public class PercentageDiscount implements DiscountStrategy {
private final double percentage;
public PercentageDiscount(double percentage) {
this.percentage = percentage;
}
@Override
public Money apply(Money original) {
return new Money(
original.amount().multiply(
BigDecimal.valueOf(1 - percentage)),
original.currency());
}
}
// 上下文类
public class PricingService {
private DiscountStrategy strategy;
public void setStrategy(DiscountStrategy strategy) {
this.strategy = strategy;
}
public Money calculatePrice(Product product) {
Money basePrice = product.getPrice();
return strategy != null ?
strategy.apply(basePrice) : basePrice;
}
}
17.2 观察者模式实现
java复制// 观察者接口
public interface OrderListener {
void onSubmitted(Order order);
}
// 被观察者
public class Order {
private final List<OrderListener> listeners = new ArrayList<>();
public void addListener(OrderListener listener) {
listeners.add(listener);
}
public void submit() {
// 业务逻辑...
listeners.forEach(l -> l.onSubmitted(this));
}
}
// 具体观察者
public class LoggingListener implements OrderListener {
@Override
public void onSubmitted(Order order) {
System.out.println("Order submitted: " + order.getId());
}
}
18. 类关系图解技巧
18.1 UML类图核心元素
code复制+---------------------+ +---------------------+
| <<interface>> | | <<abstract>> |
| DiscountStrategy| | BaseEntity |
+---------------------+ +---------------------+
| +apply(Money): Money| | #id: Long |
+----------^----------+ +----------^----------+
| |
| extends | extends
| |
+----------+----------+ +----------+----------+
| PercentageDiscount | | Product |
+---------------------+ +---------------------+
| -percentage: double | | -name: String |
+---------------------+ | -price: Money |
| +apply(Money): Money| | -stock: int |
+---------------------+ +---------------------+
18.2 关系类型速查表
| 关系类型 | 表示法 | 描述 |
|---|---|---|
| 继承 | 实线+空心三角 | extends关系 |
| 实现 | 虚线+空心三角 | implements关系 |
| 关联 | 实线箭头 | 长期持有引用 |
| 依赖 | 虚线箭头 | 临时性使用 |
| 聚合 | 空心菱形+实线 | 整体-部分,生命周期独立 |
| 组合 | 实心菱形+实线 | 强所属关系,生命周期一致 |
19. 代码质量检查要点
19.1 类复杂度检查清单
- 单一职责原则:类是否只有一个改变的理由?
- 字段数量:是否超过7个实例字段?
- 方法数量:是否超过20个方法?
- 耦合度:依赖其他类是否过多?
- 内聚性:方法是否都操作同类数据?
19.2 常见代码坏味道
- 过大的类:尝试做太多事情的上帝类
- 数据类:只有字段和getter/setter
- 拒绝遗赠:子类不需要父类的所有方法
- 过度亲密:类之间过度访问内部细节
- 重复代码:相同逻辑出现在多个类中
20. 重构技巧实战演示
20.1 提取方法重构
重构前:
java复制public class OrderProcessor {
public void process(Order order) {
// 验证逻辑
if (order.getItems().isEmpty()) {
throw new IllegalArgumentException();
}
for (Item item : order.getItems()) {
if (item.getQuantity() <= 0) {
throw new IllegalArgumentException();
}
}
// 业务处理...
}
}
重构后:
java复制public class OrderProcessor {
public void process(Order order) {
validateOrder(order);
// 业务处理...
}
private void validateOrder(Order order) {
if (order.getItems().isEmpty()) {
throw new IllegalArgumentException();
}
order.getItems().forEach(item ->
validateItem(item));
}
private void validateItem(Item item) {
if (item.getQuantity() <= 0) {
throw new IllegalArgumentException();
}
}
}
20.2 用策略模式替换条件逻辑
重构前:
java复制public class ShippingCalculator {
public double calculate(String type, double weight) {
if ("standard".equals(type)) {
return weight * 1.5;
} else if ("express".equals(type)) {
return weight * 3.0;
} else {
throw new IllegalArgumentException();
}
}
}
重构后:
java复制public interface ShippingStrategy {
double calculate(double weight);
}
public class StandardShipping implements ShippingStrategy {
@Override
public double calculate(double weight) {
return weight * 1.5;
}
}
public class ShippingCalculator {
private final ShippingStrategy strategy;
public ShippingCalculator(ShippingStrategy strategy) {
this.strategy = strategy;
}
public double calculate(double weight) {
return strategy.calculate(weight);
}
}
21. 领域驱动设计中的类应用
21.1 实体与值对象
java复制// 实体(通过ID标识)
public class Customer {
private CustomerId id; // 值对象
private String name;
// 其他字段...
// 行为方法
public void changeName(String newName) {
this.name = Objects.requireNonNull(newName);
}
}
// 值对象(通过属性标识)
public record CustomerId(String value) {
public CustomerId {
if (value == null || value.length() != 10) {
throw new IllegalArgumentException();
}
}
}
21.2 聚合根设计
java复制// 聚合根
public class Order {
private OrderId id;
private List<OrderItem> items;
private CustomerId customerId;
// 维护聚合不变性
public void addItem(Product product, int quantity) {
if (quantity <= 0) throw new IllegalArgumentException();
items.add(new OrderItem(product.getId(), quantity));
}
// 领域事件
public OrderSubmitted submit() {
// 验证逻辑...
return new OrderSubmitted(this);
}
}
// 领域事件
public record OrderSubmitted(OrderId orderId, LocalDateTime timestamp) {
public OrderSubmitted(Order order) {
this(order.getId(), LocalDateTime.now());
}
}
22. 并发环境下的类安全
22.1 不可变对象方案
java复制public final class ImmutableAccount {
private final String number;
private final BigDecimal balance;
public ImmutableAccount(String number, BigDecimal balance) {
this.number = number;
this.balance = balance;
}
public ImmutableAccount deposit(BigDecimal amount) {
return new ImmutableAccount(number, balance.add(amount));
}
}
22.2 线程安全计数器实现
java复制public class SafeCounter {
private final AtomicLong count = new AtomicLong();
public void increment() {
count.incrementAndGet();
}
public long get() {
return count.get();
}
// 乐观锁更新
public boolean compareAndSet(long expect, long update) {
return count.compareAndSet(expect, update);
}
}
23. 类与JVM内存模型
23.1 对象内存布局示例
code复制+-------------------+
| 对象头 | Mark Word(8字节)
+-------------------+
| Class指针 | 指向类元数据的指针(压缩后4字节)
+-------------------+
| 实例数据 | 所有字段的总和
+-------------------+
| 对齐填充 | 保证8字节对齐
+-------------------+
23.2 字段内存占用速查
| 数据类型 | 占用空间 |
|---|---|
| boolean | 1字节 |
| byte | 1字节 |
| char | 2字节 |
| short | 2字节 |
| int | 4字节 |
| float | 4字节 |
| long | 8字节 |
| double | 8字节 |
| 对象引用 | 4/8字节 |
注意:实际占用受JVM实现和指针压缩影响
24. 类元编程技巧
24.1 注解处理示例
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Entity {
String tableName();
}
@Entity(tableName = "users")
public class User {
//...
}
// 运行时处理
Class<User> clazz = User.class;
Entity entity = clazz.getAnnotation(Entity.class);
System.out.println("Table name: " + entity.tableName());
24.2 反射最佳实践
java复制public class ReflectionUtils {
public static void printMethods(Class<?> clazz) {
System.out.println("Methods of " + clazz.getName());
for (Method method : clazz.getDeclaredMethods()) {
System.out.println(method.getName() +
" returns " + method.getReturnType());
}
}
// 安全调用私有方法
public static Object invokePrivate(
Object target, String methodName, Object... args) throws Exception {
Method method = target.getClass()
.getDeclaredMethod(methodName);
method.setAccessible(true);
return method.invoke(target, args);
}
}
25. 类加载器深入解析
25.1 类加载器层次结构
code复制Bootstrap ClassLoader
↑
Extension ClassLoader
↑
Application ClassLoader
↑
Custom ClassLoader
25.2 自定义类加载器
java复制public class PluginClassLoader extends URLClassLoader {
public PluginClassLoader(URL[] urls) {
super(urls, ClassLoader.getSystemClassLoader().getParent());
}
@Override
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// 先检查是否已加载
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
// 优先自己加载插件类
c = findClass(name);
} catch (ClassNotFoundException e) {
// 委托给父加载器
c = super.loadClass(name, false);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
26. 类卸载与内存泄漏
26.1 类卸载条件
- 所有实例已被GC回收
- 对应的ClassLoader已被GC回收
- 该类的Class对象没有被引用
26.2 常见泄漏场景
java复制// 静态集合持有对象引用
public class LeakExample {
private static final Map<String, Object> CACHE = new HashMap<>();
public void addToCache(String key, Object value) {
CACHE.put(key, value);
}
}
// 线程未终止
public class ThreadLeak {
public void startWorker() {
new Thread(() -> {
while (true) {
// 工作逻辑...
}
}).start();
}
}
27. 类文件结构解析
27.1 类文件概览
code复制magic: 0xCAFEBABE
minor_version: 0
major_version: 55 (Java 11)
constant_pool_count: 35
constant_pool: [...]
access_flags: 0x0021 [PUBLIC, SUPER]
this_class: #5 (com/example/Test)
super_class: #6 (java/lang/Object)
interfaces_count: 0
fields_count: 2
fields: [...]
methods_count: 3
methods: [...]
attributes_count: 1
attributes: [SourceFile]
27.2 字节码示例
java复制public int add(int a, int b);
Code:
0: iload_1 // 加载第一个int参数
1: iload_2 // 加载第二个int参数
2: iadd // 执行加法
3: ireturn // 返回结果
28. 类版本兼容性
28.1 主要版本号对应表
| Java版本 | 主版本号 |
|---|---|
| 1.1 | 45 |
| 1.2 | 46 |
| 1.3 | 47 |
| 1.4 | 48 |
| 5 | 49 |
| 6 | 50 |
| 7 | 51 |
| 8 | 52 |
| 9 | 53 |
| 10 | 54 |
| 11 | 55 |
| ... | ... |
28.2 跨版本编译策略
bash复制# 使用-source和-target指定版本
javac -source 8 -target 8 MyClass.java
# 使用--release参数(Java 9+)
javac --release 8 MyClass.java
警告:低版本JVM无法运行高版本class文件,会出现UnsupportedClassVersionError
29. 类与模块系统(Java9+)
29.1 模块声明示例
java复制// module-info.java
module com.example.myapp {
requires java.base; // 隐式依赖
requires java.sql; // 显式依赖
requires transitive javafx.controls; // 传递依赖
exports com.example.model; // 导出包
exports com.example.service to com.example.tests;
opens com.example.internal; // 反射开放
}
29.2 模块化类加载规则
- 强封装:未导出的包不可访问
- 显式依赖:必须声明requires
- 服务加载:通过provides/uses声明
- 类路径模块(未命名模块)可以读取所有模块
30. 类设计终极检查清单
在完成类设计后,建议检查以下问题:
-
命名规范:
- 类名是否使用大驼峰?
- 方法名是否使用小驼峰?
- 常量是否全大写?
-
访问控制:
- 字段是否尽量private?
- 方法是否有合适的访问级别?
- 是否过度暴露实现细节?
-
单一职责:
- 类是否只做一件事?
- 是否应该拆分成更小的类?
-
不变性:
- 对象是否应该设计为不可变?
- 是否所有字段都可以是final?
-
线程安全:
- 是否需要考虑并发访问?
- 是否使用了正确的同步策略?
-
文档注释:
- 是否有清晰的类级注释?
- 公开API是否有方法注释?
- 是否说明了参数/返回值/异常?
-
测试覆盖:
- 是否容易编写单元测试?
- 是否需要模拟太多依赖?
- 是否测试了所有重要行为?
-
性能考量:
- 是否创建了过多临时对象?
- 是否有昂贵的初始化逻辑?
- 是否考虑了内存占用?
-
扩展性:
- 是否方便添加新功能?
- 是否预留了合适的扩展点?
- 是否避免了过度设计?
-
错误处理:
- 是否验证了输入参数?
- 是否处理了可能失败的情况?
- 是否抛出了合适的异常类型?
