“值语义”是什么意思,“隐式指针语义”是什么意思?
4 回答
Java 对对象类型使用隐式指针语义,对基元使用值语义。
值语义意味着您直接处理值并传递副本。这里的重点是,当您拥有价值时,您可以相信它不会在您背后改变。
使用指针语义,你没有值,你有一个“地址”。其他人可以改变那里的东西,你不知道。
C++ 中的指针语义:
void foo(Bar * b) ...
... b->bar() ...
你需要一个 * 来请求指针语义和 -> 来调用指针上的方法。
Java中的隐式指针语义:
void foo(Bar b) ...
... b.bar() ...
由于您无法选择使用值语义,因此不需要 * 也不需要 -> 和 . 之间的区别,因此是隐含的。
基本上,值语义意味着将一个值分配给另一个值会创建一个副本:
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!
Java 用于implicit pointer semantics
变量访问(您不能直接编辑引用,它会自动(隐式)解析为访问时的对象)并且还用于Pass-by-Value semantics
方法参数传递。
在 Java 应用程序中,当对象引用是方法的参数时,您传递的是引用的副本(按值传递),而不是引用本身。请注意,调用方法的对象引用和副本指向同一个对象。这是一个重要的区别。Java 应用程序在传递不同类型的参数时没有什么不同,就像 C++ 一样。Java 应用程序按值传递所有参数,因此无论类型如何,都会复制所有参数。
简而言之:Java 中的所有参数都是按值传递的。但这并不意味着对象被复制(就像 PHP4 中的默认值一样),而是对该对象的引用被复制。
您将看到有关Java 应用程序中按值传递语义的所有解释和深入示例
Java 是按值传递的。C++ 可以同时使用值和引用语义。