Setter final parameters in Java

I always programmed in java and recently I started to learn some C ++.

In C ++, it is customary to set setter parameters as const, why don't we see this as much as possible in java?

I mean, are there any drawbacks to creating a setter, for example:

public void setObject(final Object o){ this.o=o; } 

vs

 public void setObject(Object o){ this.o=o; } 

The first is to ensure that the Object o parameter remains constant across the entire set function, and not?

Edit:

The final parameter will ensure that this is NOT done:

 public void setName(String name){ name="Carlos"; this.name=name; } 

User will never be able to set a name other than "Carlos"

+6
source share
2 answers

Well, the final parameter cannot be assigned. Since the java compiler must be able to determine whether the variable / parameter is final (for anonymous inner classes), optimization is not an AFAIK factor.

Moreover, C ++ has a large set of tools that java tried to reduce. Consequently, using C ++ const string& is important when saying

  • The string is passed as a pointer, access is automatically dereferenced.
  • If the actual argument is a variable, the variable itself does not change.
  • Of course, there may be a conversion operator to pass something other than const string& .

Now java:

  • Java does not allocate objects on the stack; it saves only primitive types and descriptors of objects on the stack.
  • Java does not output parameters: a variable passed to a method call will never change its immediate value.

Back to your question:

As a setter in java, you will mostly not benefit from the final parameter. The final thing will be to not use the variable for the second assignment.

But:

 public final void setXyz(Xz xyz) { this.xyz = xyz; } 

more useful: this method cannot be overridden and, therefore, can be safely used in the constructor. (The call to the override method in the constructor will be in the context of an uninitialized child instance.)

+4
source

The slight advantage of setting the Java method parameter as final is that it does not prevent anyone from changing the state of the parameter link in this method. All this prevents the reassignment of the parameter variable to something else that does nothing for the original link and allows the parameter to be used in anonymous inner classes. If you need real security in this situation, you would strive to make your parameter types immutable, if possible.


Edit
You have sent:

 public void setObject(Object o){ o++; // this does not compile this.o=o; } 

What mixes a primitive numeric and reference type. This only makes sense if o is an integer or other numerical wrapper class, and even then the ending will not stop someone from creating:

 private void setI(final Integer i) { this.i = 1 + i; } 

But neither your code, nor this code above would affect the parameter object on the side of the calling code.


Edit
Now you have published:

 public void setName(String name){ name="Carlos"; this.name=name; } 

But then someone could write

 public void setName(final String name){ this.name= name + " Carlos"; } 

Here, where danger arises, and where the ultimate does not help. Let's say you have a class called Name:

 public class Name { private String lastName; private String firstName; public Name(String lastName, String firstName) { this.lastName = lastName; this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } } 

And then the class, Foo, with the Name field and setter. This is dangerous code:

 class Foo { private Name name; public void setName(final Name name) { name.setFirstName("Carlos"); this.name = name; } } 

Since it not only changes the state of the field, it changes the state of the Name link in the calling code, and the final modifier will not help a single bit. Solution: make the name unchanged.

eg,

 import java.util.Date; // class should be declared final public final class BetterName { private String lastName; private String firstName; private Date dateOfBirth; public BetterName(String lastName, String firstName, Date dob) { this.lastName = lastName; this.firstName = firstName; // make and store a private copy of non-immutable reference types dateOfBirth = new Date(dob.getTime()); } // only getters -- no setters public String getLastName() { return lastName; } public String getFirstName() { return firstName; } public Date getDateOfBirth() { // return copies of non-immutable fields return new Date(dateOfBirth.getTime()); } } 
+6
source

Source: https://habr.com/ru/post/989895/


All Articles