I am using Java 8. I haven't found another question that fits mine exactly, and I've come across some conflicting information on best practices with what I'm trying to do.
I'm creating a POJO which is essentially a business object - to be returned by my API - that will have its fields initialized from another object.
I'm using the @Data
lombok annotation to generate the getters/setters/toString.
I'm wondering which of the following options would align with best practices:
Note: It is guaranteed that authUser
will be not null when calling the User
constructor.
1. Null-checks with if-statements and default field values
@Data
public class User {
private String userId = "";
private String fullName = "";
private String email = "";
private Set<String> roles = Collections.emptySet();
public User(AuthUser authUser, Set<String> roles) {
if (authUser.getUserId() != null) {
this.userId = authUser.getUserId();
}
if (authUser.getFullName() != null) {
this.fullName = authUser.getFullName();
}
if (authUser.getEmail() != null) {
this.email = authUser.getEmail();
}
if (roles != null) {
this.roles = roles;
}
}
}
I feel like this is a safe/generic way to do this, and I could store the values retrieved from the getters to local variables so the get calls aren't redundant.
2. Null-checks using ternaries with redundant get calls
@Data
public class User {
private String userId;
private String fullName;
private String email;
private Set<String> roles;
public User(AuthUser authUser, Set<String> roles) {
this.userId = authUser.getUserId() == null ? "" : authUser.getUserId();
this.fullName = authUser.getFullName() == null ? "" : authUser.getFullName();
this.email = authUser.getEmail() == null ? "" : authUser.getEmail();
this.roles = roles == null ? Collections.emptySet() : roles;
}
}
The purpose of this is to reduce code-cluttering, but I believe Clean Code argues against ternaries, so I'd probably not prefer this option for the sake of readability.
3. Null-checks with Optionals without redundant get calls
@Data
public class User {
private String userId;
private String fullName;
private String email;
private Set<String> roles;
public User(AuthUser authUser, Set<String> roles) {
this.userId = Optional.ofNullable(authUser.getUserId()).orElse("");
this.fullName = Optional.ofNullable(authUser.getFullName()).orElse("");
this.email = Optional.ofNullable(authUser.getEmail()).orElse("");
this.roles = Optional.ofNullable(roles).orElse(Collections.emptySet());
}
}
The purpose of this is to reduce code-cluttering and redundant get calls without creating local variables in order to remove that redundancy. I think this is preferable to ternaries but am not sure.
4. Null-checks with Apache StringUtils.defaultString and CollectionUtils.emptyIfNull
@Data
public class User {
private String userId;
private String fullName;
private String email;
private Set<String> roles;
public User(AuthUser authUser, Set<String> roles) {
this.userId = StringUtils.defaultString(authUser.getUserId());
this.fullName = StringUtils.defaultString(authUser.getFullName());
this.email = StringUtils.defaultString(authUser.getEmail());
this.roles = CollectionUtils.emptyIfNull(roles);
}
}
This a little shorter than using Optional
s, but I feel like using native Java is preferable to third-party libraries (ApacheUtils
is already included as a dependency).
if (null == (attribute = parameter.getAttribute())) attribute = default;
. \$\endgroup\$