Subclasses @Builder anotação Lombok a postura correta

I. Antecedentes

No desenvolvimento real, às vezes você precisa usar @Builder anotação subclasses Lombok usar o esquema construtor constrói o objeto de subclasse.

Classe pai:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Parent {
    private Long id;

    private String name;
}

subclasse

import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@Builder
public class Child extends Parent{


}

Neste momento, embora a anotação adicionado em subclasses @Builder, mas já que não há subclasse atributo, como mostrado abaixo, não pode usar o padrão do construtor.

 

 

Segundo, a análise

Lombok.Builder lendo a fonte, não só entendeu anotação @Builder pode ser usado em sala de aula, ele também pode ser usado no construtor.

Então tente a seguinte redação:

@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@Builder
public class Child extends Parent {

    @Builder
    private Child(Long id, String name) {
        super(id, name);
    }
}

testes de unidade de gerência re acima, resultados suportam o modo de construtor, mas o estranho é, não através de uma única medida.

java.lang.AssertionError: 
Esperado: 1024
Actual: null

Então olhamos para Child.class o código decompiled:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.chujianyun.libs.lombok;

public class Child extends Parent {
    private Child(Long id, String name) {
        super(id, name);
    }

    public static Child.ChildBuilder builder() {
        return new Child.ChildBuilder();
    }

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Child)) {
            return false;
        } else {
            Child other = (Child)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                return super.equals(o);
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Child;
    }

    public int hashCode() {
        int result = super.hashCode();
        return result;
    }

    public String toString() {
        return "Child()";
    }

    public Child() {
    }

    public static class ChildBuilder {
        private Long id;
        private String name;

        ChildBuilder() {
        }

        public Child build() {
            return new Child();
        }

        public String toString() {
            return "Child.ChildBuilder()";
        }

        public Child.ChildBuilder id(final Long id) {
            this.id = id;
            return this;
        }

        public Child.ChildBuilder name(final String name) {
            this.name = name;
            return this;
        }
    }
}

Encontrou a razão, ao usar notas @Builder no construtor sub-classe e full-parâmetros, haverá BUG, ​​ou seja, a versão final () função simplesmente retorna um construtor de parâmetro nulo cria um objeto filho, então propriedade "adotada construtor de modo id e definir o nome "final" perdido ".

 

Então, como resolver este problema?

Mais uma vez, voltamos para a fonte do comentário @Builder:

If a member is annotated, it must be either a constructor or a method. If a class is annotated,
* then a private constructor is generated with all fields as arguments
* (as if {@code @AllArgsConstructor(access = AccessLevel.PRIVATE)} is present
* on the class), and it is as if this constructor has been annotated with {@code @Builder} instead.

Encontrado, que é adicionado para a classe correspondente ao construtor particular contém todos os atributos, e adicionando anotações sobre construtor @Builder.

Então, nós escrever o código pode ter um conflito, nós ter a seguinte redacção:

import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class Child extends Parent {

    @Builder
    private Child(Long id, String name) {
        super(id, name);
    }
}

O único final medida pela

Nós olhamos para o código compilado neste momento:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.chujianyun.libs.lombok;

public class Child extends Parent {
    private Child(Long id, String name) {
        super(id, name);
    }

    public static Child.ChildBuilder builder() {
        return new Child.ChildBuilder();
    }

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Child)) {
            return false;
        } else {
            Child other = (Child)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                return super.equals(o);
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Child;
    }

    public int hashCode() {
        int result = super.hashCode();
        return result;
    }

    public String toString() {
        return "Child()";
    }

    public Child() {
    }

    public static class ChildBuilder {
        private Long id;
        private String name;

        ChildBuilder() {
        }

        public Child.ChildBuilder id(final Long id) {
            this.id = id;
            return this;
        }

        public Child.ChildBuilder name(final String name) {
            this.name = name;
            return this;
        }

        public Child build() {
            return new Child(this.id, this.name);
        }

        public String toString() {
            return "Child.ChildBuilder(id=" + this.id + ", name=" + this.name + ")";
        }
    }
}

Neste ponto, a função build () é o estado que precisamos.

A partir do código compilado, podemos ver claramente através do padrão lógica Lombok núcleo construtor @Builder alcançado.

Ou seja, a estrutura interna da classe, as propriedades de atribuição dentro da classe, chamar o construtor contém todos os atributos de um objeto quando a compilação é criada.

 

Mais detalhes podem ser analisar cuidadosamente @Builder código fonte anotada e comentários, consulte o manual oficial  https://projectlombok.org/features/Builder

Em terceiro lugar, o resumo

Encontrar problemas estranhos não devem facilmente deixar ir.

Analisar os problemas têm passos, como se você pode ter um olhar para as instruções de código fonte, você também pode olhar para o código compilado, você também pode desmontar e assim por diante, que fez um comentário para observar o impacto dos arquivos de classe. Você também pode ver o manual oficial.

 

 

-------------------------------------------------- ---

Vejo programadores CSDN de 1024 eventos (24 de Outubro de 2019 prazo)

Se eu tenho um blog para ajudá-lo, e não há tempo para receber o navegador que código de verificação micro-canal para ajudar a apoiar-me o meu ponto de louvor:

 

 
Publicado 379 artigos originais · Louvor obteve 862 · Visualizações 1,32 milhão +

Acho que você gosta

Origin blog.csdn.net/w605283073/article/details/102470537
Recomendado
Clasificación