在Java中如何定义一个标准的类结构_Java类设计规范解析

Java类名须用PascalCase且与文件名严格一致;字段默认private,配校验型getter/setter;构造方法需覆盖无参及全参场景;equals/hashCode/toString须成对重写并遵循规范。

类名必须用 PascalCase 且匹配文件名

Java 要求 public 类的名称必须与文件名完全一致,且首字母大写的驼峰命名(PascalCase)。如果类声明为 public 但文件名是 userdao.javaUserDaoImpl.java,编译器会直接报错:class UserDao is public, should be declared in a file named UserDao.java

常见错误包括:

  • 类名用了下划线(user_dao)或全小写(userdao
  • 文件保存为 UTF-8 with BOM,导致编译器读取到不可见字符
  • 在 IDE 中重命名类但未同步改文件名(尤其 IntelliJ 默认不联动)

成员变量优先使用 private + getter/setter

标准 Java 类中,所有字段应默认声明为 private,不暴露内部状态。需要外部访问时,按需提供符合 JavaBeans 规范的 getXXX() / setXXX() 方法(布尔类型可用 isXXX())。

注意点:

  • setter 应校验参数(如非空、范围),避免对象进入非法状态
  • 返回集合字段时,getter 不要直接返回内部引用,应返回副本(如 new ArrayList(this.items))或不可变包装(Collections.unmodifiableList(this.items)
  • 不要为只读字段提供 setter;也不要为常量(static final)生成 getter(除非有特殊封装逻辑)
public class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name == null || name.trim().isEmpty()) {
            throw new IllegalArgumentException("name cannot be null or empty");
        }
        this.name = name.trim();
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException("age must be between 0 and 150");
        }
        this.age = age;
    }
}

构造方法应覆盖常用初始化场景

一个“标准”的 Java 类通常至少提供一个无参构造方法(方便反射、序列化、框架如 Spring 使用),以及一个全字段构造方法(便于测试和明确依赖)。若字段较多,可考虑使用 Builder 模式,但不要在基础实体类里强行套用。

关键原则:

  • 避免在构造方法中调用可被子类重写的方法(可能引发 NullPointerException,因子类字段尚未初始化)
  • 构造方法内不做耗时操作(如 I

    /O、网络请求),这违背单一职责,也影响对象创建性能
  • 若类不可继承,显式加 final 修饰类;若部分方法不应被重写,用 final 修饰对应方法

重写 equals/hashCode/toString 需严格遵循约定

只要类会被放入 HashSetHashMap 或用于断言比较(如 JUnit 的 assertEquals),就必须正确重写 equals()hashCode()。IDE 自动生成的版本基本可用,但要注意:

  • 只基于「业务上认为相等」的字段参与比较(例如 User 类通常比对 id,而非 nameage
  • 若用 Lombok,确保 @EqualsAndHashCode 明确指定了 includeexclude 字段,否则默认包含所有非静态非瞬态字段,易出错
  • toString() 应简洁可读,推荐用 Objects.toStringHelper(Guava)或 String.format,避免拼接大量字段影响日志性能

最容易被忽略的是:一旦重写了 equals(),就必须重写 hashCode(),否则违反契约,HashMap 查找会失效。