#java #immutability
#java #неизменяемость
Вопрос:
Я хочу создать глубоко неизменяемую точку с плавающей точкой x и плавающей точкой y, вот мой код:
public final class Point {
private final float x;
private final float y;
//getter
public float getX(){return x;}
public float getY(){return y;}
//constructor
Point(float x,float y){this.x = x;this.y = y;}
//equals
public boolean equals(Point p1) {
if (p1 == this) {return true;}
Point p = p1;
return Float.compare(x, p.x) == 0
amp;amp; Float.compare(y, p.y) == 0;
}
//toString
public String toString() {
return "x=" x " y=" y;
}
Однако, когда я тестировал, я обнаружил, что могу назначить новую точку существующей точке:
public static void main(String[] args) {
Point p1 = new Point(0,0);
Point p2 = new Point(0,0);
Point p3 = new Point(0,1);
p1 = p3; //This operation is working, so it is not immutable.
System.out.println(p1);
System.out.println(p1.equals(p2));
}
Что я сделал не так? Как его улучшить? Спасибо!
Комментарии:
1.
Point
глубоко неизменяемый. Проблема заключается в вашем понимании переменных Java: любая переменная типаPoint
всегда является ссылкой наPoint
объект и может быть изменена (если не помеченаfinal
).2. Если вы используете
final Point p1 = new Point(0,0);
попытку переназначенияp1
, это приведет к ошибке компиляцииerror: cannot assign a value to final variable p1
.3.
Point
класс не имеет глубины , поэтому обсуждение глубокой неизменяемости бессмысленно (каламбур).
Ответ №1:
Ваш Point
класс уже глубоко неизменяемый!
p1 = p3; //This operation is working, so it is not immutable.
Неверно. Вы все еще можете переназначать переменные неизменяемых типов. Вот почему они называются переменными. Вы можете изменить то, что они хранят. Вы можете изменить p1
его так, чтобы он сохранял ссылку на другой Point
объект, но чего вы не можете сделать, так это изменить свойства (например, координаты X или Y) Point
объекта, на который p1
ссылается.
Чтобы сделать так, чтобы вы не могли изменять значение переменной, вы должны создать переменную final
:
final Point p1 = ...;
Вы можете написать тот же код с String
помощью s, которые, как известно, являются неизменяемыми. Вы бы сказали, что String
s тоже изменчивы?
String p1 = "a";
String p2 = "b";
String p3 = "c";
p1 = p3; // this operation is working, does this mean that strings are mutable? No!
System.out.println(p1);
System.out.println(p1.equals(p2));
Ответ №2:
То, как вы его разработали, Point
уже глубоко неизменяемо.
Когда вы выполняете присваивание p1 = p3
, вы не изменяете сам Point
объект, вы просто меняете, на какой объект ссылается переменная.
Если вы не хотите, чтобы переменные переназначались, пометьте их следующим final
образом:
final Point p1 = new Point(0,0);
final Point p2 = new Point(0,0);
final Point p3 = new Point(0,1);
p1 = p3; // This won't work now
Ответ №3:
хорошо, сначала конструкторы в классе java, вы должны создать его «общедоступным» .. если вы хотите создать новый экземпляр (объект) этого класса.
second..java является строго типизированным lenguage ..тогда, если вы создали переменную того же типа. вы могли бы заменить его (в этом примере p1 = p3 ) обе переменные являются классом Point .
с уважением!