Skip to content

S02-08 面向对象-JavaBean

[TOC]

JavaBean

什么是 JavaBean

在 Java 开发中,JavaBean 是一个极其重要的概念,尤其是当我们刚刚聊完“三层架构”和数据在各层之间流转(如 POJO、DTO、VO)之后,理解 JavaBean 恰逢其时。

JavaBean:并不是一个特定的类,也不是什么高深的技术,它仅仅是一种“类设计规范”或“约定”。

只要你的普通 Java 类遵循了这套规范,我们就可以把它叫做一个 JavaBean。

四大核心规范

JavaBean 的四大核心规范 (The Rules):

要想成为一个合格的 JavaBean,你的类必须严格遵守以下四个条件:

  1. 所有的属性(成员变量)必须是 private:

    • 目的: 保证数据的安全性(封装特性),防止外部直接通过 对象.属性 的方式随意篡改数据。
  2. 必须提供一个 public 的无参构造方法:

    • 目的: 绝大多数 Java 框架(如 Spring、MyBatis、Hibernate)在底层都是通过反射机制 (Reflection) 来自动创建对象的。反射默认调用的就是无参构造方法。如果没有它,框架在尝试帮你自动实例化对象时就会直接报错。
  3. 必须提供 publicgettersetter 方法:

    • 目的: 提供对外的、标准化的数据访问接口。
    • 命名规范极其严格:
      • 普通属性 name,方法必须叫 getName()setName()
      • 如果是 boolean 类型的属性(如 married),获取方法通常叫 isMarried(),设置方法叫 setMarried()
  4. 建议实现 java.io.Serializable 接口 (序列化):

    • 目的: JavaBean 通常用来承载数据(比如从数据库查出来的用户信息)。这些数据经常需要跨网络传输给前端,或者保存到硬盘(缓存)中。实现序列化接口,能让这个对象变成二进制流在网络中安全穿梭。

标准 JavaBean 代码示例:

结合以上四点,一个标准的 JavaBean 应该是这样的(可以通过快捷键 Alt + Insert 自动生成无参构造、有参构造、Getter/Setter):

java
import java.io.Serializable;

// 1. 实现 Serializable 接口
public class UserBean implements Serializable {

    // 强烈建议加上序列化版本号 (虽然不加也能跑,但加上更规范)
    private static final long serialVersionUID = 1L;

    // 2. 属性私有化 (private)
    private String username;
    private int age;
    private boolean active;

    // 3. 必须有公共的无参构造方法 (就算你不写,编译器默认也会送一个;但如果你写了有参构造,就必须手动把无参构造补上!)
    public UserBean() {
    }

    // (可选) 为了自己用着方便,可以加一个有参构造
    public UserBean(String username, int age, boolean active) {
        this.username = username;
        this.age = age;
        this.active = active;
    }

    // 4. 提供标准的 Getter 和 Setter
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    // 注意 boolean 类型的 Getter 是 is 开头
    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }
}

应用场景

为什么要制定这套规范(应用场景):

你可能会觉得:这也太啰嗦了吧?写几个变量非要搞出这么多代码!

这主要是为了迎合框架和组件化开发

  1. 和数据表相对应:框架会根据数据库中的表,自动生成相对应的 JavaBean,它们的对应关系如下:

    image-20260226181627434

  2. 框架添加功能(自动化赋值): 比如你在前端网页的表单里填了用户名和密码点击提交。后端的 Spring MVC 框架会自动 new 一个你的 JavaBean,然后通过反射调用 setUsername()setPassword(),把你填的数据自动塞进去。如果你的方法名不规范,框架就找不到该往哪塞数据了。

    image-20260227171059099

  3. 框架查询功能

    将从数据库中查询出来的结果封装成多个javabean对象,然后将多个javabean对象放到集合中,一起返回给页面,进行展示。

    image-20260227172050132

  4. JSP/前端模板引擎:

    早期的 JSP 技术中有 <jsp:useBean> 标签,后来的 Thymeleaf 或 Vue 等前端技术,在读取后端传来的数据时,底层其实也是去找 JavaBean 的 getter 方法,而不是直接读变量。

JavaBean vs POJO

概念辨析:JavaBean vs POJO:

这两个词经常被混用,面试官也很喜欢问:

  • POJO (Plain Old Java Object - 简单老式 Java 对象): 它是一个“泛指”。只要你是一个普通的 Java 类,没有继承什么乱七八糟的框架特有类(比如没继承 HttpServlet),你就是一个 POJO。
  • JavaBean: 它是一个“特指”。它是严格遵守了上述四大规范的 POJO。

一句话总结:JavaBean 是一种要求更严格的 POJO。 在三层架构中,我们在层与层之间传递的 DTO、VO、Entity,绝大多数情况下都必须写成 JavaBean 的规范。

现代 Java 开发中的神器

现代 Java 开发中的“救星”:

手写这些 Getter/Setter 和无参构造确实非常枯燥,所以现代开发中我们有两件神器:

  1. Lombok 插件:

    只需要在类头上加一个 @Data 注解,它就会在编译时自动帮你生成所有的 Getter/Setter、无参构造以及 toString() 等方法。源码非常干净。

  2. Java 14+ 的 Record 类:

    如果你使用的是较新的 JDK,并且你的数据对象创建后就不再修改(只读),你可以直接使用 record 关键字,一行代码搞定:

    java
    public record User(String username, int age) {}