“值语义”和“指针语义”是什么意思?

2022-09-02 01:15:03

“值语义”是什么意思,“隐式指针语义”是什么意思?


答案 1

Java 对对象类型使用隐式指针语义,对基元使用值语义。

值语义意味着您直接处理值并传递副本。这里的要点是,当你有一个价值时,你可以相信它不会在你背后改变。

使用指针语义,你没有值,你有一个“地址”。其他人可以改变那里的东西,你无法知道。

C++中的指针语义:

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

您需要一个 * 来请求指针语义,->来调用 pointee 上的方法。

Java中的隐式指针语义:

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

由于您没有使用值语义的选择,因此不需要 *,也不需要 -> 和 . 之间的区别,因此是隐式的。


答案 2

基本上,值语义意味着将一个值分配给另一个值会创建一个副本:

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只知道少数基元类型,其中包括 、和 ,以及以这种方式运行的枚举。所有其他类型都使用引用语义,这意味着将一个值赋值到另一个值实际上会重定向指针,而不是复制基础值:intdoublebooleanchar

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.

但是,有一些警告。例如,许多引用类型 (, ...) 实际上是不可变的。无法更改它们的值,并且对它们的任何赋值都会覆盖旧值。StringInteger

此外,参数仍按值传递。这意味着传递给函数的对象的值可以更改,但其引用不能:

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!