SpringBoot 中的 Setter-Getter-Constructor

发布: (2026年1月5日 GMT+8 01:54)
8 min read
原文: Dev.to

Source: Dev.to

为什么不直接使用 obj.name = "Rahul" 而使用 obj.setName("Rahul")

主要原因(3 Purpose)

#原因如果不这么做会怎样
1数据安全 – 如果字段是 public,任何人都可以写入错误数据。Vendor v = new Vendor(); v.age = -500; // ❌ 错误,但 Java 不会报错
2校验 – 可以在 Setter 中检查数据。(示例见下)
3封装 – 为字段的读取/修改提供受控接口。
  • Setter → 在数据进入之前进行校验。
  • Getter → 将数据以正确的格式返回。
public class Vendor {
    private int age;

    public void setAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative");
        }
        this.age = age;
    }

    public int getAge() {
        return age;
    }
}

Spring Boot 中 Getter/Setter 的作用

  • JacksonHibernate 等库遵循 JavaBeans 规范。
  • 如果字段是 public 且没有 Getter/Setter,Spring Boot 将无法将数据转换为 JSON,或者在数据库中会被设置为 null

比喻 – Direct Variable = 把家门敞开(任何人都可以进来)。
Getter/Setter = 在门口安排守卫。

如何在另一个文件中使用模型类 (CloudVentor)

1️⃣ 在 Service 类中使用构造函数、Getter 和 Setter

package com.restapi.demo.service;

import com.restapi.demo.model.CloudVentor;
import org.springframework.stereotype.Service;

@Service
public class CloudVendorService {

    public void demoMethod() {

        // ----- 1. CONSTRUCTOR -----
        CloudVentor vendor1 = new CloudVentor("C1", "Amazon", "USA", "123456");

        // ----- 2. GETTER -----
        String name = vendor1.getVendorName();
        System.out.println("Vendor का नाम है: " + name);

        if (vendor1.getVendorAddress().equals("USA")) {
            System.out.println("International Vendor है");
        }

        // ----- 3. SETTER -----
        vendor1.setVendorPhoneNumber("9876543210");

        // Empty‑constructor + setters
        CloudVentor vendor2 = new CloudVentor();   // खाली ऑब्जेक्ट
        vendor2.setVendorId("C2");
        vendor2.setVendorName("Flipkart");
    }
}

注意 – Spring Boot 通常会隐式调用构造函数或 Setter,但在返回响应时需要 Getter。

2️⃣ 在 Controller 中的隐藏魔法(自动绑定)

package com.restapi.demo.controller;

import com.restapi.demo.model.CloudVentor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/cloudvendor")
public class CloudVendorAPIService {

    private CloudVentor cloudVendor;   // अस्थायी स्टोरेज (DB की जगह)

    // ----- POST : JSON → Object (Constructor/Setter) -----
    @PostMapping
    public String createCloudVendorDetails(@RequestBody CloudVentor details) {

        // आवश्यकता पड़ने पर मैन्युअल Setter
        details.setVendorName(details.getVendorName().trim());

        this.cloudVendor = details;
        return "Cloud Vendor Created Successfully";
    }

    // ----- GET : Object → JSON (Getter) -----
    @GetMapping("{vendorId}")
    public CloudVentor getCloudVendorDetails(@PathVariable String vendorId) {

        if (cloudVendor != null && cloudVendor.getVendorId().equals(vendorId)) {
            return cloudVendor;   // Getter कॉल हो कर JSON बनता है
        }
        return null;
    }
}

方法类型概述

方法何时使用?语法示例
Constructor创建新对象时(首次)CloudVentor c1 = new CloudVentor("1","A","B","C");
Getter读取数据、打印或在逻辑中使用String n = c1.getVendorName();
Setter对象创建后更改数据(更新)c1.setVendorAddress("New Delhi");

完整模板 – 如何在另一个类中使用一个类的 Getter/Setter/构造函数

// --------- Model (CloudVentor) ----------
package com.restapi.demo.model;

public class CloudVentor {
    private String vendorId;
    private String vendorName;
    private String vendorAddress;
    private String vendorPhoneNumber;

    // ----- All‑args Constructor -----
    public CloudVentor(String vendorId, String vendorName,
                       String vendorAddress, String vendorPhoneNumber) {
        this.vendorId = vendorId;
        this.vendorName = vendorName;
        this.vendorAddress = vendorAddress;
        this.vendorPhoneNumber = vendorPhoneNumber;
    }

    // ----- No‑args Constructor -----
    public CloudVentor() {}

    // ----- Getters -----
    public String getVendorId() { return vendorId; }
    public String getVendorName() { return vendorName; }
    public String getVendorAddress() { return vendorAddress; }
    public String getVendorPhoneNumber() { return vendorPhoneNumber; }

    // ----- Setters -----
    public void setVendorId(String vendorId) { this.vendorId = vendorId; }
    public void setVendorName(String vendorName) { this.vendorName = vendorName; }
    public void setVendorAddress(String vendorAddress) { this.vendorAddress = vendorAddress; }
    public void setVendorPhoneNumber(String vendorPhoneNumber) {
        this.vendorPhoneNumber = vendorPhoneNumber;
    }
}
// --------- Service/Controller (उदाहरण) ----------
package com.restapi.demo.service;   // या .controller

import com.restapi.demo.model.CloudVentor;
import org.springframework.stereotype.Service;

@Service
public class ExampleUsage {

    public void demo() {
        // Constructor
        CloudVentor v = new CloudVentor("V01", "Amazon", "USA", "111222333");

        // Getter
        System.out.println("Name : " + v.getVendorName());

        // Setter
        v.setVendorPhoneNumber("999888777");
    }
}

结论

  • Getter/Setter 对数据的安全性和框架集成是必需的。
  • Direct field access 不会进行验证,Spring Boot 等工具无法对数据进行序列化/反序列化。

理解这些原则后,你可以编写清晰、安全且框架友好的代码。 🚀

1. 基本结构(模型类)

Student.java(模型类)

package com.example.demo.model;

public class Student {
    private String id;
    private String name;
    private int age;

    // 1. 默认构造器(无参)
    public Student() {
    }

    // 2. 参数化构造器(全参)
    public Student(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // 3. Getter 方法
    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    // 4. Setter 方法
    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

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

2. 在另一个类中使用此类

案例 1 – 在 Service 类中使用

StudentService.java (Business Logic)

package com.example.demo.service;

import com.example.demo.model.Student;

public class StudentService {

    // 1. 构造函数的使用(用于创建对象)
    public Student createNewStudent() {
        Student student = new Student("S1", "Rahul", 25); // 参数化构造函数
        return student;
    }

    // 2. Setter 的使用(用于修改数据)
    public void updateStudentName(Student student, String newName) {
        student.setName(newName); // 调用 Setter
    }

    // 3. Getter 的使用(用于读取数据)
    public void printStudentDetails(Student student) {
        System.out.println("ID: " + student.getId());   // 调用 Getter
        System.out.println("Name: " + student.getName());
        System.out.println("Age: " + student.getAge());
    }
}

案例 2 – 在 Controller 类中使用(Spring Boot REST API)

StudentController.java (API Endpoints)

package com.example.demo.controller;

import com.example.demo.model.Student;
import com.example.demo.service.StudentService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/students")
public class StudentController {

    private final StudentService studentService;

    // 构造函数注入(依赖)
    public StudentController(StudentService studentService) {
        this.studentService = studentService;
    }

    // 1. GET API(使用 Getter)
    @GetMapping("/{id}")
    public Student getStudent(@PathVariable String id) {
        Student student = studentService.createNewStudent();
        student.setId(id);               // 使用 Setter
        return student;                 // 自动转换为 JSON(使用 Getter)
    }

    // 2. POST API(使用 Constructor + Setter)
    @PostMapping
    public Student addStudent(@RequestBody Student newStudent) {
        // newStudent 中的请求体数据已经到达(Jackson 使用了 Setter/Constructor)
        System.out.println("New Student: " + newStudent.getName()); // 使用 Getter
        return newStudent;
    }
}

案例 3 – 在 Main 类中使用(测试)

MainApplication.java (Test Class)

package com.example.demo;

import com.example.demo.model.Student;
import com.example.demo.service.StudentService;

public class MainApplication {
    public static void main(String[] args) {
        // 1. 使用构造函数(创建对象)
        Student student1 = new Student("S1", "Amit", 22);

        // 2. 使用 Setter(更改数据)
        student1.setAge(23);

        // 3. 使用 Getter(读取数据)
        System.out.println("Name: " + student1.getName());

        // 使用 Service 类
        StudentService studentService = new StudentService();
        Student student2 = studentService.createNewStudent();
        studentService.printStudentDetails(student2);
    }
}

3. Lombok 的使用(如果不想手写 Getter/Setter)

Student.java(Lombok 版本)

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Data               // Auto‑generates getters, setters, toString, equals, hashCode
@NoArgsConstructor  // Default Constructor
@AllArgsConstructor // Parameterized Constructor
public class Student {
    private String id;
    private String name;
    private int age;
}

现在,你可以直接使用 student.getId()student.setName("Rahul") 等方法,而无需手动编写!

4. Java Records 的使用(用于不可变对象)

StudentRecord.java(不可变 DTO)

public record StudentRecord(String id, String name, int age) {}
  • 自动生成的 getter:id(), name(), age()
  • 没有 setter(不可变)
  • 使用场景:API 响应、配置数据、DTO

5. 结论 (Conclusion)

Use Case如何使用?
Model Class (JPA Entity)Traditional class + Lombok (@Data)
REST API DTOsJava Records (Immutable) or Lombok
Service/Controller LogicGetter / Setter / Constructor calls
Testing (Main Class)new Student() + setX() + getX()

Recommendation

  • Spring Boot + JPA → Lombok (@Data)
  • API DTOs → Java Records
  • Manual control → Traditional getters/setters

这样您就可以轻松地在任何类中使用 getter、setter 和构造函数! 🚀

Back to Blog

相关文章

阅读更多 »

递归的迭代

将简化 HTML 转换为 Markdown 并使用语法树 在我的一个副项目或“宠物”项目中,我编写了一个小型 parser,用于简化 HTML,p...