简体   繁体   中英

How to use @lombok.Builder.Default with java records

Before java 16 you would use a class with a lombok value annotation, because records didn't exist yet (except in preview). If you wanted a builder and wanted a field to have a default value, you would annotate it like so:

@Builder
@Value
public class SomeClass {
    private final int id;
    private final String someString;
    @Builder.Default
    private final String someOtherString = "DefaultVal";

}

This would generate the following class:

public final class SomeClass {
    private final int id;
    private final String someString;
    private final String someOtherString;

    SomeClass(int id, String someString, String someOtherString) {
        this.id = id;
        this.someString = someString;
        this.someOtherString = someOtherString;
    }

    private static String $default$someOtherString() {
        return "DefaultVal";
    }

    public static SomeClassBuilder builder() {
        return new SomeClassBuilder();
    }

    public int getId() {
        return this.id;
    }

    public String getSomeString() {
        return this.someString;
    }

    public String getSomeOtherString() {
        return this.someOtherString;
    }

    public boolean equals(final Object o) {
        if (o == this) return true;
        if (!(o instanceof SomeClass)) return false;
        final SomeClass other = (SomeClass) o;
        if (this.getId() != other.getId()) return false;
        final Object this$someString = this.getSomeString();
        final Object other$someString = other.getSomeString();
        if (this$someString == null ? other$someString != null : !this$someString.equals(other$someString))
            return false;
        final Object this$someOtherString = this.getSomeOtherString();
        final Object other$someOtherString = other.getSomeOtherString();
        if (this$someOtherString == null ? other$someOtherString != null : !this$someOtherString.equals(other$someOtherString))
            return false;
        return true;
    }

    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        result = result * PRIME + this.getId();
        final Object $someString = this.getSomeString();
        result = result * PRIME + ($someString == null ? 43 : $someString.hashCode());
        final Object $someOtherString = this.getSomeOtherString();
        result = result * PRIME + ($someOtherString == null ? 43 : $someOtherString.hashCode());
        return result;
    }

    public String toString() {
        return "SomeClass(id=" + this.getId() + ", someString=" + this.getSomeString() + ", someOtherString=" + this.getSomeOtherString() + ")";
    }

    public static class SomeClassBuilder {
        private int id;
        private String someString;
        private String someOtherString$value;
        private boolean someOtherString$set;

        SomeClassBuilder() {
        }

        public SomeClassBuilder id(int id) {
            this.id = id;
            return this;
        }

        public SomeClassBuilder someString(String someString) {
            this.someString = someString;
            return this;
        }

        public SomeClassBuilder someOtherString(String someOtherString) {
            this.someOtherString$value = someOtherString;
            this.someOtherString$set = true;
            return this;
        }

        public SomeClass build() {
            String someOtherString$value = this.someOtherString$value;
            if (!this.someOtherString$set) {
                someOtherString$value = SomeClass.$default$someOtherString();
            }
            return new SomeClass(id, someString, someOtherString$value);
        }

        public String toString() {
            return "SomeClass.SomeClassBuilder(id=" + this.id + ", someString=" + this.someString + ", someOtherString$value=" + this.someOtherString$value + ")";
        }
    }
}

Now that we are well beyond java 16 and records have been added, I was trying to get this to work with those records. @Builder seems to work fine, but how can I use @Builder.Default with records?

@Builder
public record SomeClass(
        int id,
        String someString,
        @Builder.Default
        String someOtherString = "DefaultVal"
) {
}

The above code obviously doesn't work, because you can't assign a value in a record property definition. Is there a way to use @Builder.Default with records? For instance, can @Builder.ObtainVia be used for this or does that really only work with toBuilder() ?

If you're looking to solve default values you can use this:

public record SomeClass(
    int id,
    String someString,
    String someOtherString){
    public SomeClass(){
        this(UUID.randomUUID(), "default","default");
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM