I don’t know exactly what you meant by semantics, but we can see the question from various perspectives.
Clarity
Use methods Setter can be more confusing because if someone else will read your code.
It may incorrectly assume that the method Setter whether or not it performs any logic within it, so it needs to navigate to the methods and look at what they do.
Note in the other answers that they always end up inferring something or putting a condition. Imagine a system with multiple cases of this and you can extrapolate how much complexity it will add to everyone’s life.
Always use the simplest solution. In this case, always use direct assignment when possible.
I imagine that this may seem "ugly" to some, mainly because when we start using object orientation, we get the impression that any direct manipulation of attributes somehow breaks the encapsulation.
But the scope of the class is owned by itself. A class does not need secrets for itself, or we begin to engage in insanity. We could say that a class that encapsulates itself has multiple personalities?
Effect
Imagining now that the setters only attribute, the final effect would be the same as the assignment. However, this is not always so simple, especially where there is competition involved.
Understand competition as the act of accessing and modifying the same attribute or object from different threads at the same time.
In competing scenarios, you should always use modifiers final
or volatile
, because they guarantee that the state of the variables will be written in the main memory and all the threads will see the correct value. Otherwise a thread can read the old cache value.
An efficient way to share objects between threads is using immutable objects. In this case, it is recommended to use final
in all attributes. Example:
private final String nome;
private final float n1;
In the above example, the attributes final
can only be assigned once and this must occur until the constructor is finished. Attributes final
shall not be delegated to a Setter.
Maintenance and avoiding silly errors
In addition to attributes, we can also declare the parameters as final
, that is, they cannot have the value changed. Example:
public Aluno(final String n, final float n1, final float n2) {...}
How that helps?
First, you avoid silly mistakes like:
public Aluno(String nome, float nota1, float nota2) {
this.nome = nome;
this.nota1 = nota1;
nota2 = nota2;
}
Believe me, I’ve corrected silly mistakes like this one above in production many times. This would be avoided if the parameters were final
:
public Aluno(final String nome, final float nota1, final float nota2) {
this.nome = nome;
this.nota1 = nota1;
nota2 = nota2; //erro de compilação aqui
}
This also helps to remember that you should not modify method parameters to reuse it as a variable, as if it would save memory or something like.
Running logic
If there is a need to execute some logic in the method Setter, suggest an alternative:
public Aluno(String nome, float nota1, float nota2) {
this.nome = nome;
this.nota1 = verificarNotaValida(nota1);
this.nota2 = verificarNotaValida(nota2);
}
public void setNota1(float nota1) {
this.nota1 = verificarNotaValida(nota1);
}
Extracting validation logic allows for more reuse and makes code clear.