注解@Builder和@Accessors---简化get/set方法

本文介绍了Lombok的@Builder和@Accessors注解,用于简化Java对象的get/set方法。@Builder方便了对象初始化,避免大量setter调用,提高代码可读性。@Accessors提供了fluent、chain和prefix三种模式,分别控制getter和setter的命名以及setter方法返回对象实例,便于链式调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用前的准备

@Builder和@Accessors都是lombok下的注解,都可以用于简化get/set方法。
要使用Lombok,需要添加插件并导入依赖。插件直接在IDEA的settings-Plugins中搜索lombok,下载后重启IDEA即可,依赖如下:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
</dependency>

@Builder注解

@Builder 注解可以更方便的在对象初始化的时候对属性进行赋值,不用大量的调用 setter 方法,代码更易于阅读与编写。

@Data
@Builder
@NoArgsConstructor
public class User {
    String name;
    String address;
   public static void main(String[] args) {
        //builder方式赋值。取值仍然要通过get。
        User user=new User().builder().name("teacher").address("河南省").build();
        //set方式赋值
        user.setName("student");
        user.setAddress("北京市");
    }
}

@Accessors注解

@Accessors 有3个值:flunt,chain,prefix;

  1. fluent ,Boolean类型,默认false,且flunt为true,则chain默认为true。
    如果为true,name的getter就是 name(),setter方法就是name(T newValue)。
  2. chain ,Boolean类型,默认false,且flunt为true,则chain默认为true。
    如果为true,产生的setter返回的this即对象实例本身而不是void,因此可以直接再使用set方法或者调用其他函数。
  3. prefix ,一系列string类型。如果显示,属性必须加上某些定义的前缀。前缀被提取出来后才是属性名。字符都是字母,紧接着前缀后的字符一定不能是小写字母。例如,pepper对前缀p不是相等匹配,而跟pEpper是匹配的(也就意味着属性的基本名字是epper)。

注意:@Accessors注解可以在类和属性上使用。如果@Accessors注解在一个属性上,再对那个属性的类的@Accessors注解就会被忽略。

@Data
@Accessors(fluent = true)    
@NoArgsConstructor
public class User {
    String name;
    String Address;

    public static void main(String[] args) {
        //accesstor flunt=true,此时默认chain=true
        User user=new User().name("teacher").Address("河北"); //赋值,类似set方法
        String address=user.Address();                       //取值,类似get方法
    }
}
@Data
@Accessors(chain = true)
@NoArgsConstructor
public class User {
    String name;
    String Address;

    public static void main(String[] args) {
        //accesstor  chain=true,未设置flunt,默认flunt=false
        User user=new User().setName("teacher").setAddress("河北"); //赋值,类似set方法
        String address=user.getAddress();                       //取值,类似get方法
    }
}
<think>好的,用户现在想了解关于“Result实体类”的内容。我需要先理解用户的具体需求是什么。通常来说,Result实体类在Java开发中常用于封装接口的返回结果,特别是在RESTful API中,用于统一返回格式,包含状态码、消息数据等信息。 首先,我要确定用户是想要一个通用的Result类的示例,还是想了解某个特定框架或项目中的Result类实现。比如,Spring Boot项目中常用的Result封装方式。用户可能是在开发过程中遇到了需要统一返回结构的问题,或者在学习他人代码时看到了这样的类,想要了解其结构作用。 接下来,我需要回忆常见的Result类设计。通常包含code、msg、data这三个字段,code表示状态码,msg是提示信息,data是返回的数据。可能还会有成功失败的静态工厂方法,方便快速创建对象。此外,泛型的使用可以让data字段支持不同类型的数据。 然后,用户可能想知道为什么需要这样的实体类。统一返回结构的好处在于前端处理起来更方便,所有的响应都有相同的格式,便于解析错误处理。同时,后端开发也能保持一致性,减少重复代码。 可能还需要考虑一些高级特性,比如链式调用(使用@Accessors(chain = true)),或者结合Lombok注解简化代码。另外,状态码的定义是否遵循HTTP标准,或者使用自定义的业务状态码,这也是需要说明的地方。 用户可能存在的疑问包括:如何处理分页数据?这时候data可以是一个包含分页信息的对象。或者,如何自定义错误码消息?可以通过枚举或者常量类来管理状态码消息,保持代码的可维护性。 此外,需要确保示例代码的正确性,比如使用Lombok的@Data注解自动生成gettersetter,使用泛型T来定义data的类型。静态方法successerror的返回类型应该是Result<T>,并且正确设置各个字段的值。 最后,可能需要给出使用示例,比如在Controller层返回Result.success(data),或者在异常处理中返回Result.error(code, msg)。这有助于用户理解如何在实际项目中应用这个类。 总结来说,用户需要一个清晰、结构合理的Result实体类介绍,包括其作用、设计思路、代码示例以及使用场景。同时,需要考虑到用户可能的后续问题,提前在回答中覆盖相关内容,比如泛型的使用、状态码管理、与异常处理的结合等,确保回答全面且有帮助。</think>以下是一个典型的通用`Result`实体类的设计解析与实现示例,用于统一封装接口返回结果: --- ### 一、核心作用 $$R = \lbrace code, msg, data \rbrace$$ - **标准化响应结构**:统一所有接口的返回格式 - **状态码管理**:通过`code`字段明确业务状态 - **数据封装**:用`data`字段承载实际返回内容 - **错误信息传递**:通过`msg`字段传递友好提示 --- ### 二、基础版实现(含Lombok) ```java @Data @Accessors(chain = true) public class Result<T> { private Integer code; // 状态码(如200=成功,500=错误) private String msg; // 提示信息(如"操作成功") private T data; // 泛型承载业务数据 // 成功快捷方法 public static <T> Result<T> success(T data) { return new Result<T>() .setCode(200) .setMsg("success") .setData(data); } // 错误快捷方法 public static <T> Result<T> error(int code, String msg) { return new Result<T>() .setCode(code) .setMsg(msg); } } ``` --- ### 三、增强特性实现 #### 1. 分页支持 ```java @Data public class PageResult<T> { private Long total; // 总记录数 private List<T> rows; // 当前页数据 } // 带分页的成功返回 public static <T> Result<PageResult<T>> pageSuccess(Long total, List<T> rows) { return Result.success(new PageResult<T>().setTotal(total).setRows(rows)); } ``` #### 2. 状态码枚举 ```java public enum ResultCode { SUCCESS(200, "操作成功"), BAD_REQUEST(400, "参数错误"), UNAUTHORIZED(401, "未授权"), FORBIDDEN(403, "禁止访问"), NOT_FOUND(404, "资源不存在"), INTERNAL_ERROR(500, "系统异常"); private final int code; private final String msg; // 构造函数+getter } ``` --- ### 四、典型使用场景 #### 1. Controller层返回 ```java @GetMapping("/users/{id}") public Result<User> getUser(@PathVariable Long id) { User user = userService.getById(id); return user != null ? Result.success(user) : Result.error(ResultCode.NOT_FOUND.getCode(), "用户不存在"); } ``` #### 2. 异常处理器 ```java @ExceptionHandler(Exception.class) public Result<?> handleException(Exception e) { log.error("系统异常", e); return Result.error(ResultCode.INTERNAL_ERROR.getCode(), "服务暂不可用"); } ``` --- ### 五、响应结构对比 | 场景 | 原始响应 | Result封装后响应 | |----------------|-----------------------------|------------------------------------------| | 成功查询用户 | `{"name":"张三","age":25}` | `{"code":200,"msg":"success","data":{...}}` | | 参数校验失败 | HTTP 400空响应 | `{"code":400,"msg":"姓名不能为空","data":null}` | | 服务异常 | HTTP 500错误页面 | `{"code":500,"msg":"系统繁忙","data":null}` | --- ### 六、高级扩展方案 #### 1. 国际化支持 ```java // 通过MessageSource获取本地化消息 public static <T> Result<T> error(int code, String msgKey, Object... args) { String localizedMsg = messageSource.getMessage(msgKey, args, LocaleContextHolder.getLocale()); return new Result<T>().setCode(code).setMsg(localizedMsg); } ``` #### 2. 链路追踪集成 ```java @Data public class Result<T> { private String traceId; // 从MDC中获取追踪ID // 修改success方法: public static <T> Result<T> success(T data) { return new Result<T>() .setTraceId(MDC.get("X-B3-TraceId")) .setCode(200) .setData(data); } } ``` --- ### 七、设计模式应用 #### 1. 建造者模式变体 ```java public static class Builder<T> { private Result<T> result = new Result<>(); public Builder<T> code(int code) { result.setCode(code); return this; } public Result<T> build() { if(result.getCode() == null) { result.setCode(200); } return result; } } ``` #### 2. 策略模式 ```java public interface ResultDecorator { void decorate(Result<?> result); } // 添加安全审计装饰器 public class AuditDecorator implements ResultDecorator { @Override public void decorate(Result<?> result) { result.setAuditId(UUID.randomUUID().toString()); } } ``` --- ### 八、性能优化建议 1. **对象池化**:对高频使用的Result对象进行池化复用 2. **预定义实例**: ```java public static final Result<?> EMPTY_SUCCESS = success(null); public static final Result<?> UNAUTHORIZED = error(401, "未授权"); ``` 3. **禁用序列化**:对`data=null`的字段进行序列化过滤 ```java @JsonInclude(JsonInclude.Include.NON_NULL) private T data; ``` --- ### 九、Spring Boot集成示例 #### 1. 自动包装响应 ```java @RestControllerAdvice public class ResultWrapper implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class converterType) { return !returnType.getParameterType().isAssignableFrom(Result.class); } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType mediaType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { return Result.success(body); } } ``` #### 2. Swagger文档适配 ```java @Schema(name = "Result", description = "通用响应实体") public class Result<T> { @Schema(description = "状态码", example = "200") private Integer code; @Schema(description = "业务数据") private T data; } ``` --- ### 十、最佳实践建议 1. **状态码规范**:建议遵循HTTP状态码语义 2. **敏感数据过滤**:在`data`字段序列化前进行脱敏处理 3. **版本控制**:通过`@Deprecated`标记旧版本返回字段 4. **监控集成**:统计各`code`的出现频率用于系统健康分析 完整示例代码可参考: [https://github.com/spring-projects/spring-boot/tree/main/spring-boot-samples](https://github.com/spring-projects/spring-boot/tree/main/spring-boot-samples)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值