Что означают «семантика значений» и «семантика указателей»? - PullRequest
16 голосов
/ 03 октября 2008

Что подразумевается под «семантикой значения» и что подразумевается под «семантикой неявного указателя»?

Ответы [ 4 ]

14 голосов
/ 03 октября 2008

По сути, семантика значения означает, что при назначении одного значения другому создается копия:

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!
13 голосов
/ 03 октября 2008

Java использует неявную семантику указателей для типов объектов и семантику значений для примитивов.

Семантика значений означает, что вы имеете дело непосредственно со значениями и что вы передаете копии. Дело в том, что когда у вас есть ценность, вы можете верить, что она не изменится за вашей спиной.

С семантикой указателя у вас нет значения, у вас есть «адрес». Кто-то может изменить то, что там, вы не можете знать.

Семантика указателя в C ++:

void foo(Bar * b) ...
... b->bar() ...

Вам нужно * для запроса семантики указателя и -> для вызова методов в pointee.

Семантика неявных указателей в Java:

void foo(Bar b) ...
... b.bar() ...

Поскольку у вас нет выбора использования семантики значений, * не требуется, ни различие между -> и., Следовательно, неявное.

1 голос
/ 03 октября 2008

Java передается по значению. C ++ может использовать семантику как значений, так и ссылок.

http://javadude.com/articles/passbyvalue.htm

1 голос
/ 03 октября 2008

Java использует implicit pointer semantics при доступ к переменной (вы не можете напрямую редактировать ссылку, она автоматически (неявно) разрешается в объект при доступе), а также использует метод Pass-by-Value semantics при передача параметров .

Чтение Семантика передачи по значению в приложениях Java :

В приложениях Java, когда объект ссылка является параметром для метода, вы передаете копию ссылка (передача по значению), а не ссылка сама. Обратите внимание, что ссылка на объект вызывающего метода и копия указывает на то же самое объект. Это важный различие. Java-приложение делает ничего по другому при прохождении параметры разных типов, такие как C ++ делает. Java-приложения проходят все параметры по значению, что делает копии всех параметров независимо от тип.

Short: все параметры в Java передаются по значению. Но это не означает, что объект копируется (как по умолчанию в PHP4), но ссылка на этот объект копируется.

Все объяснения и подробные примеры вы найдете в Семантика передачи по значению в приложениях Java

...