Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

206
Visualizações
this-keyword is not allowed to access a field in constructors of records

I have the following record:

public record A(List<String> list) {
    public A {
      this.list = new ArrayList<>(list);
    }
}

But I get this compile error:

Cannot assign a value to final variable

On the other hand this compiles:

public record A(List<String> list) {
    public A {
      list = new ArrayList<>(list);
    }
}

Why is this?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

The reason is given in JEP 395: Records (emphasis mine):

The canonical constructor may be declared explicitly with a list of formal parameters which match the record header, as shown above. It may also be declared more compactly, by eliding the list of formal parameters. In such a compact canonical constructor the parameters are declared implicitly, and the private fields corresponding to record components cannot be assigned in the body but are automatically assigned to the corresponding formal parameter (this.x = x;) at the end of the constructor. The compact form helps developers focus on validating and normalizing parameters without the tedious work of assigning parameters to fields.

In other words, with the compact canonical constructor, you're updating the constructor parameter, and that constructor parameter is then assigned to the field in code generated by the compiler.

This means that declaring

public record A(List<String> list) {
    public A {
        this.list = new ArrayList<>(list);
    }
}

in essence generates:

public record A(List<String> list) {
    public A(List<String> list) {
        this.list = new ArrayList<>(list);
        this.list = list;
    }
}

Which attempts to assign the list field twice. This is not allowed for final fields.

On the other hand, the following code:

public record A(List<String> list) {
    public A {
        list = new ArrayList<>(list);
    }
}

Results in:

public record A(List<String> list) {
    public A(List<String> list) {
        list = new ArrayList<>(list);
        this.list = list;
    }
}

Which is perfectly fine as the list field is only assigned once.

over 4 years ago · Santiago Trujillo Relatório

0

When you refer this.list it implies property of the current object/class, and in records all the props are final

it's similar to

final String s = "ABC";

now if you try

s = "PQR";

it will give you the same error cause 's' is final

public record A(List<String> list){
    public A{
      this.list=new ArrayList<>(list);
    }
}

although you can do this

public record A(List<String> list){
    public A(List<String> list){
      this.list=new ArrayList<>(list);
    }
}

records' all the properties are final, you cannot reassign value to record that's one reason to use records

if you want to reassign values use classes

reason why you are not getting error in second part is because you're creating compact constructor, What you should really do is

public record A(List<String> list){
    public A(List<String> list){
      this.list=new ArrayList<>(list);
    }
    public A{
      if(!Objects.nonNull(list){
        throw new IllegalArgumentException("List must not be empty")
      }
    }

}

in other words, when you initialize new record, it will simply set that parameter values to it's properties and when you try to reassign using this keyword it will definitely throw error since it's properties are final

and for second code block you are just assigning value to your parameter 'list' you are not changing your class properties

I hope this answers your question.

for more details go here

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda