Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

202
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!