web-dev-qa-db-fra.com

Lombok constructeur pour vérifier non null et non vide

J'ai une classe avec des variables pour lesquelles je ne veux pas qu'elle soit nulle ou vide. Existe-t-il un moyen d'utiliser le générateur Lombok pour définir la propriété? Je peux utiliser @NonNull mais je ne pourrai pas vérifier s'il est vide ou non. Évidemment, l’autre option est d’écrire mon propre constructeur qui effectue toutes ces vérifications. Par exemple:

class Person {
    @NonNull
    private String firstName;
    @NonNull
    private String lastName;

    public static class PersonBuilder() {
        // .
        // .
        // .
        public Person build() {
            //do checks for empty etc and return object
        }
    }
}
7
user1692342

La réponse de Maxim Kirilov est incomplète. Il ne vérifie pas les chaînes vides/vides.

J'ai déjà rencontré le même problème et je me suis rendu compte qu'en plus d'utiliser @NonNull et @Builder de Lombok, surchargez le constructeur avec un modificateur d'accès privé, où vous pouvez effectuer les validations. Quelque chose comme ça:

private Person(final String firstName, final String lastName) {
    if(StringUtils.isBlank(firstName)) {
        throw new IllegalArgumentException("First name can't be blank/empty/null"); 
    }
    if(StringUtils.isBlank(lastName)) {
        throw new IllegalArgumentException("Last name can't be blank/empty/null"); 
    }
    this.firstName = firstName;
    this.lastName = lastName;
}

En outre, le lancement de IllegalArgumentException a plus de sens (au lieu de NPE) lorsque String a des valeurs vides, vides ou null.

10
Kedar Prabhu

L'annotation du générateur devrait résoudre votre problème:

@Builder
class Person {
    @NonNull
    private String firstName;
    @NonNull
    private String lastName;
}

Le code généré est:

class Person {
    @NonNull
    private String firstName;
    @NonNull
    private String lastName;

    @ConstructorProperties({"firstName", "lastName"})
    Person(@NonNull String firstName, @NonNull String lastName) {
        if(firstName == null) {
            throw new NullPointerException("firstName");
        } else if(lastName == null) {
            throw new NullPointerException("lastName");
        } else {
            this.firstName = firstName;
            this.lastName = lastName;
        }
    }

    public static Person.PersonBuilder builder() {
        return new Person.PersonBuilder();
    }

    public static class PersonBuilder {
        private String firstName;
        private String lastName;

        PersonBuilder() {
        }

        public Person.PersonBuilder firstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Person.PersonBuilder lastName(String lastName) {
            this.lastName = lastName;
            return this;
        }

        public Person build() {
            return new Person(this.firstName, this.lastName);
        }

        public String toString() {
            return "Person.PersonBuilder(firstName=" + this.firstName + ", lastName=" + this.lastName + ")";
        }
    }
}

Dans ce cas, la validation nulle aura lieu lors de la construction de l'objet. 

6
Maxim Kirilov

J'ai fait quelque chose comme ça,

class Person {
    private String mFristName;
    private String mSecondName;

    @Builder
    Person(String firstName, String secondName) {
        mFristName = PreCondition.checkNotNullOrEmpty(firstName);
        mSecondName = PreCondition.checkNotNullOrEmpty(secondName);
    }
}

class PreCondition {

    static <T> T checkNotNullOrEmpty(T instance) {
        if (instance == null || (instance instanceof String && ((String) instance).isEmpty())) {
            throw new NullOrEmptyException();
        }
        return instance;
    }

    static class NullOrEmptyException extends RuntimeException {
        NullOrEmptyException() {
            super("Null or Empty");
        }
    }
}
1
Suryavel TR