SpringBoot 中的 Setter-Getter-Constructor
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 的作用
- Jackson、Hibernate 等库遵循 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 DTOs | Java Records (Immutable) or Lombok |
| Service/Controller Logic | Getter / 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 和构造函数! 🚀