In Java, I feel that using Private when declaring an attribute and not declaring a Setter method for it gives the same outcome as using Final when declaring the attribute, both allow the variable to stay constant.
If that is the case, what is the benefit of using Final in this scenario?
CodePudding user response:
Even without a setter other methods in the class can change the attribute so it's a completely different concept. Many would argue it's not a good thing to do (it adds "side effects" to your program) but it's still possible.
CodePudding user response:
The answer is Encapsulation
Consider this.
public class Point
{
int x, y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
//no getters or setters needed, I can just modify or read x and y directly.
}
public class FinalPoint
{
public final Point point;
public FinalPoint(int x, int y)
{
this.point = new Point(x, y);
}
//no getters needed, I'll just read point since it is public
}
Right now, this FinalPoint
has a final Point
as an instance field. On the one hand, it means that that instance field cannot be reassigned. However, the fields of that instance field can definitely be reassigned.
For example.
FinalPoint p = new FinalPoint(1, 2);
p.point.x = 4; //I have now modified state! final did not protect us here
The final
keyword is powerful, but it does not mean that your data is unchangeable. It only means that that surface level reference is unchangeable - it will force a reference to always point to the same object. That does not stop the object its pointing to from changing it's internal state as much as it wants. The only guarantee final
makes is that you always be pointing at the same object.
Which brings us to encapsulation. Encapsulation was created to solve this exact problem and more.
Consider this.
public class EncapsulatedPoint
{
private Point point;
public EncapsulatedPoint(int x, int y)
{
this.point = new Point(x, y);
}
public int getX() { return this.point.x; }
public int getY() { return this.point.y; }
}
Now, because I have encapsulated Point
and exposed only the data I can safely expose, I have protected myself from modification. It is impossible to change this object (without using reflection or other hacks the designers are actively removing). It truly is Immutable.
Of course, Encapsulation is not superior to using final
. There is a time and a place for both. Knowing when and where allows you to make your software secure.
CodePudding user response:
Private variables will never access from the outside of the class and Final will never change by taking input from the user.
CodePudding user response:
Assumed you are talking about variables, the keywords final
and private
define different characteristics.
The keyword final
denies any changes to the variable and throws compilation errors
when modified or changed. However, without specifying public
or private
, with the default package-private
access modifier, it could be accessed by other classes in the same package
once initialized (text with bold
fonts are corrected by @charsofire and @MC Emperor).
On the other hand, the keyword private
rejects the idea of being called by other classes, even in the same package. But it could be changed and modified by methods in the same class, even without setter
or getter
methods.
For example in the same class
of the same package
:
public class Student {
private int score;
final int id;
public Student(int id, int score) {
this.id = id;
this.score = score;
}
public void modifyGrade(int newScore) {
// Accepted
this.score = newScore;
}
public void modifyID(int id) {
// Rejected
this.id = id;
}
}
And in different class
of the same package
:
public class School {
public static void main(String[] args) {
Student student = new Student(0, 35);
// Accepted
System.out.println(student.id);
// Rejected
System.out.println(student.score);
// Accepted
student.modifyGrade(29);
// throws exception
student.id = 5;
// Not visible
student.score = 29;
}
}
Hope this answer helps you well,
and many thanks again to both @charsofire and @MC Emperor, who helped to clarify significantly in this answer.