Вопрос может быть слишком широким, потому что можно довольно широко спорить о том, что должно означать слово «вести себя». Но в некоторой степени мы можем разобраться в этом:
Самый короткий ответ может быть: Нет, это невозможно.
Немного более сложный ответ может быть: Нет, это не пока невозможно позволить классу (или, точнее, объекту) вести себя как примитивное значение.
Длинный ответ:
Существуют усилия для достижения поведения, которое может приблизиться к тому, что вы пытаетесь достичь. Соответствующее ключевое слово здесь Типы значений .
Некоторые ресурсы:
Однако это не поддерживается в текущих версиях Java и JVM, и это может занять некоторое время, пока детали не будут разобраны.
До тех пор, есть некоторые возможные обходные пути для достижения желаемой цели.
Самое простое решение - это то, которое вы уже предложили: вы всегда возвращаете новый экземпляр вместо изменения данного объекта.
Пример, который вы показали в вопросе, может быть не лучшим примером для иллюстрации, потому что метод getAdjacent
, который вы показали, на самом деле может быть static
методом. Он не использует экземпляр, к которому он вызван, каким-либо образом.
Тогда вы всегда можете быть уверены, что получили новый экземпляр для каждой модификации. В противном случае представьте этот фрагмент кода:
Point a = new Point(1,2);
Point b = new Point(3,4);
a.add(b);
System.out.println(a); // What does this print?
В зависимости от реализации метода add
поведение может быть неясным. Если это было реализовано так:
public void add(Point other) {
this.x += other.x;
this.y += other.y;
}
тогда точка a
будет изменена, и результат будет (4,6)
.
Но если это было реализовано так
public Point add(Point other) {
return new Point(this.x+other.x, this.y+other.y);
}
, тогда a
останется неизменным, а результат будет (1,2)
.
В общем, создание чего-то вроде Point
неизменяемого в основном реализует этот стиль программирования. Таким образом, вы можете сделать переменные x
и y
в своем классе final
, чтобы вы всегда могли быть уверены, что объект не может быть изменен после его создания:
public class Point {
// Note that these are FINAL:
private final int x;
private final int y;
public Point(int nx, int ny) {
this.x = nx;
this.y = ny;
}
...
}
Существуют некоторые дополнительные соображения по поводу разработки такой, казалось бы, тривиальной вещи, как Point
класс (некоторые из которых я упомянул в этом ответе ), но их обсуждение выходит за рамки этого ответа.