@Builder、@SuperBuilder、@Wither、@Accessors

(58) 2024-08-18 21:01:01

详细请看:https://blog.51cto.com//?source=drt

@Builder

构造器模式

  • 它创建了一个private 的全参构造器。也就意味着 无参构造器没有; 同时也意味着这个类不可以直接构造对象。

  • 它为每一个属性创建了一个同名的方法用于赋值,代替了setter,而该方法的返回值为对象本身。

 

import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Builder.Default; import lombok.Data; import lombok.NoArgsConstructor; @Builder @Data @AllArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructorpublic class UserBean { private Integer id; private String userName; @Default private String example = ""; @Singular private List<String> favorites; }
@Singular这个注解可以这样操作list了 UserBean u = UserBean.builder() .id(1001) .userName("polly") .favorite("music") .favorite("movie") .build();

@Default可以设置默认值,如果不加注解,在使用@Builder构造对象时,默认值失效。

@SuperBuilder

@Builder并不支持父类成员属性的构造,@SuperBuilder注解的出现,就是用来解决这个问题。父类和子类上都加上@SuperBuilder,这样子类就可以正常获取到父类的成员属性进行builder构造了。

@SuperBuilder的toBuilder属性默认关闭,如果开启,则所有的父类应该也要开启,通过设置true,所有的类实例会拥有toBuilder方法,这是一个类似深拷贝的一个方法,不会改变原有实例的属性,生成一个新的实例。在toBuilder中有赋值的属性则会改变为赋值属性,没有赋值的以调用的实例中的值为准。

详细请看:@Builder、@SuperBuilder、@Wither、@Accessors

@Wither

用wither方式构建对象

我们可以设置一个必选参数的构造器,如下:

import lombok.AllArgsConstructor; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.experimental.Wither; @RequiredArgsConstructor @Wither public class ApiClient { @NonNull private String appId; @NonNull private String appKey; private String endpoint = "http://www.baidu.com/myservice"; }

这样使用时就可以这样:

@Test public void test1() { ApiClient client1=new ApiClient("10001", "abcdefgh"); System.out.println(client1); Object client2 = client1.withEndpoint("http://127.0.0.1/"); System.out.println(client2); }

是不是优雅了很多?而且实际上使用时也使用链式语法:

ApiClient client1=new ApiClient("10001", "abcdefgh") withEndpoint("http://127.0.0.1/");

另外还有一个小细节,前面的示例输出如下:

com.pollyduan.wither.ApiClient@ecom.pollyduan.wither.ApiClient@470e2030

这个日志表明,with() 返回的对象并不是原来的对象,而是一个新对象,这很重要。

@Accessors

访问器模式,是给一个普通的Bean增加一个便捷的访问器,包括读和写。

它有两种工作模式,fluent和chain,举例说明:

import lombok.Data; import lombok.experimental.Accessors; @Accessors(fluent = true) @Data public class UserBean { private Integer id; private String userName; private String password; }

和 Builder 类似,但更小巧,而且不影响属性的读写,只不过使用属性同名字符串代替了getter和setter。

fluent=true时,默认chain=true。即get、set方法名使用属性名,同时支持链式set

 

THE END

发表回复