По сути, семантика значения означает, что при назначении одного значения другому создается копия:
int x = 1;
int y = x;
x = 2; // y remains the same!
Особый случай - это вызов функции, которому передается аргумент:
void f(int x) {
x = 5;
}
int a = 1;
f(a);
// a is still 1
Это фактически одно и то же для Java и C ++. Однако Java знает только несколько примитивных типов, среди которых int
, double
, boolean
и char
, а также перечисления, которые ведут себя таким образом. Все другие типы используют ссылочную семантику, что означает, что присвоение одного значения другому фактически перенаправляет указатель вместо копирования базового значения:
class Foo {
int x;
public Foo(int x) { this.x = x; }
}
Foo a = new Foo(42);
Foo b = a; // b and a share the same instance!
a.x = 32;
//b.x is now also changed.
Однако есть несколько предостережений. Например, многие ссылочные типы (String
, Integer
…) фактически являются неизменяемыми. Их значение не может быть изменено, и любое присвоение им заменяет старое значение.
Кроме того, аргументы по-прежнему передаются по значению. Это означает, что значение объекта, переданного функции, может быть изменено, но его ссылка не может:
void f(Foo foo) {
foo.x = 42;
}
void g(Foo foo) {
foo = new Foo(42);
}
Foo a = new Foo(23);
f(a);
// a.x is now 42!
Foo b = new Foo(1);
g(b);
// b remains unchanged!