'值语义'是什么意思,'隐式指针语义'是什么意思?
答案 0 :(得分:14)
基本上,值语义意味着将一个值分配给另一个值会创建一个副本:
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!
答案 1 :(得分:13)
Java正在使用Object类型的隐式指针语义和基元的值语义。
值语义意味着您直接处理值并传递副本。 这里的要点是,当你有一个价值时,你可以相信它不会在你的背后发生变化。
使用指针语义,你没有值,你有一个'地址'。 其他人可以改变那里的东西,你无法知道。
C ++中的指针语义:
void foo(Bar * b) ...
... b->bar() ...
你需要*来询问指针语义和 - >调用指针对象的方法。
Java中的隐式指针语义:
void foo(Bar b) ...
... b.bar() ...
由于您没有选择使用值语义,因此不需要*,也不需要区分 - >和。因此是隐含的。
答案 2 :(得分:1)
Java在变量访问上使用implicit pointer semantics
(您无法直接编辑引用,它会自动(隐式)在访问时解析为Object)并使用Pass-by-Value semantics
on 方法参数传递。
阅读Pass-by-value semantics in Java applications:
在Java应用程序中,当一个对象时 reference是方法的参数, 你正在传递一份副本 引用(按值传递),而不是 参考本身。请注意 调用方法的对象引用和 副本指向相同的 宾语。这很重要 区别。 Java应用程序 路过时没什么不同 不同类型的参数,如C ++ 确实。 Java应用程序通过所有 参数按值,从而制作 所有参数的副本,无论如何 类型。
简短:Java中的所有参数都按值传递。但这并不意味着会复制Object(如PHP4中的默认值),但会复制对该对象的引用。
上看到所有解释和深入的示例答案 3 :(得分:1)
Java是按值传递的。 C ++可以使用值,值和引用语义。