2015-06-08 27 views
18

Ho una classe denominata come "XYZClientWrapper", che sono seguente struttura:Lombok escludere proprietà dal costruttore

@Builder 
XYZClientWrapper{ 
String name; 
String domain; 
XYZClient client; 
} 

Quello che voglio nessuna funzione accumulo generato per la proprietà "client XYZClient;" Lombok supporta questo caso d'uso?

risposta

40

Sì, è possibile inserire @Builder su un costruttore o un metodo statico (di fabbrica), contenente solo i campi desiderati.

Disclosure: Sono uno sviluppatore di Lombok.

+0

Per quanto mi riguarda, grazie per aver rivelato di essere uno sviluppatore di lombok ;-). Questo costruttore o metodo statico (di fabbrica) può essere non pubblico? – markvgti

+0

Sì, potrebbe avere visibilità, incluso 'private'. La divulgazione indica che la risposta o l'opinione potrebbero essere di parte. In questo caso non è rilevante, ma ho preso l'abitudine di aggiungerlo a tutte le mie risposte relative al lombok. –

+17

Mi sono imbattuto in questa domanda e risposta poiché ho in mente la stessa domanda. La soluzione del costruttore non è davvero una buona soluzione nel mio caso. Ho una classe con 29 proprietà (un'entità) e voglio solo che una di esse non sia inclusa nel builder (in effetti: l'id). Non esiste un modo per escludere il meccanismo proprio come in @ToString? Il motivo principale per usare Lombok è evitare il disordine. Un Costruttore con 28 parametri non è quello che voglio vedere. – Staratnight

0

alternativa, ho scoperto che la marcatura di un campo come finale, statica o statica finale incarica @Builder ignorare questo campo.

@Builder 
public class MyClass { 
    private String myField; 

    private final String excludeThisField = "bar"; 
} 

Lombok 1.16.10

+1

Grazie Stephan per la risposta. Nel mio caso non funziona poiché il campo che voglio ignorare è derivato dalla classe genitore. – Staratnight

+1

Cosa ?! Uso il costruttore quotidianamente con i campi finali, come potrebbero essere ignorati? : D al momento utilizza la versione 1.16.12 – Dominik

+0

@Stephan Come potrebbe essere vero? Voglio dire: lo scopo del pattern builder è di evitare costruttori con tutti questi lunghi elenchi di parametri. Il campo in finale non ha nulla a che fare: lo scopo del costruttore è quello di riunire tutti i parametri in "modo metodo di concatenamento" invece di un enorme colpo. Inoltre, l'ho controllato e l'aggiunta di final non ha alcun effetto sulla costruzione del builder. – Piohen

2

Creare il costruttore in codice e aggiungere un setter privato per la vostra proprietà.

@Builder 
XYZClientWrapper{ 
    String name; 
    String domain; 
    XYZClient client; 

    public static class XYZClientWrapperBuilder { 
     private XYZClientWrapperBuilder client(XYZClient client) { return this; } 
    } 
} 
1

ho scoperto che ero in grado di implementare un "guscio" della classe Builder statica, aggiungere il metodo voglio nascondere con un modificatore di accesso privato, e non è più accessibile nel generatore. Allo stesso modo, posso aggiungere metodi personalizzati al costruttore.

package com.something; 

import lombok.AccessLevel; 
import lombok.AllArgsConstructor; 
import lombok.Builder; 
import lombok.Data; 
import lombok.Getter; 
import lombok.NoArgsConstructor; 
import lombok.Setter; 

import javax.persistence.AttributeOverride; 
import javax.persistence.AttributeOverrides; 
import javax.persistence.Column; 
import javax.persistence.Embedded; 
import javax.persistence.Entity; 
import java.time.ZonedDateTime; 

@Data 
@Entity 
@Builder 
@AllArgsConstructor 
@NoArgsConstructor 
public class MyClass{ 

    //The builder will generate a method for this property for us. 
    private String anotherProperty; 

    @Embedded 
    @AttributeOverrides({ 
      @AttributeOverride(name = "localDateTime", column = @Column(name = "some_date_local_date_time")), 
      @AttributeOverride(name = "zoneId", column = @Column(name = "some__date_zone_id")) 
    }) 
    @Getter(AccessLevel.PRIVATE) 
    @Setter(AccessLevel.PRIVATE) 
    private ZonedDateTimeEmbeddable someDateInternal; 

    public ZonedDateTime getSomeDate() { 
     return someDateInternal.toZonedDateTime(); 
    } 

    public void setSomeDate(ZonedDateTime someDate) { 
     someDateInternal = new ZonedDateTimeEmbeddable(someDate); 
    } 

    public static class MyClassBuilder { 
     //Prevent direct access to the internal private field by pre-creating builder method with private access. 
     private MyClassBuilder shipmentDateInternal(ZonedDateTimeEmbeddable zonedDateTimeEmbeddable) { 
      return this; 
     } 

     //Add a builder method because we don't have a field for this Type 
     public MyClassBuilder someDate(ZonedDateTime someDate) { 
      someDateInternal = new ZonedDateTimeEmbeddable(someDate); 
      return this; 
     } 
    } 

}