我的Java书解释说,要使用对象,我们可以将它们分配给引用变量。那与指向对象的指针有何不同?Java有指针吗?
谢谢 :)
我的Java书解释说,要使用对象,我们可以将它们分配给引用变量。那与指向对象的指针有何不同?Java有指针吗?
谢谢 :)
引用有点像指针,但你不能对它进行算术操作...虽然它更不透明。虽然底层的比特可能是虚拟内存中的地址,但它们不必是。它们只是一种访问对象(或表示空值)的方式。因此,虽然它们并不完全相同,但如果你习惯于将指针视为“标识对象或导航到对象的一种方式”(在某种意义上),那么这些想法也适用于引用。
Java本身没有指针(与C#不同,C#既有引用又有指针——后者在“不安全”代码中使用)。
Cat x = new Cat();
这行代码在内存中创建了一个Cat对象,并将其引用存储在x中。
现在,x包含对Cat对象的引用,但如果你执行以下操作:
x = x + 1;
这不会像在C语言中那样给出下一个内存地址,而是会导致编译器错误。Java不允许控制引用或内存位置。
术语“引用”和“指针”基本上是等效的。我看到的许多关于Java基础知识的文献都声称Java没有指针。但是,如果您尝试使用null
引用,就会得到一个NullPointerException
。所以这都是语义问题。
(真正的区别在于,在C或C++中,“指针”一词严格意义上指的是一种整数,恰好是某些数据的内存地址。而在Java中,“引用”一词更接近于C++的“引用”概念。您甚至无法直接使用内存地址,但使用方式相同。)
引用是一个指针,你通常看不到它的值(即内存地址)。唯一允许的操作是将其设置(从另一个引用)并通过它引用所引用的对象。它可以从引用值表达式(如new运算符)或从另一个引用设置(在语法上是一个简单的引用值表达式)。
就Java语法而言——确实,Java没有指针,但为了澄清情况,Java Runtime里有指针。
每次发生GC时,你存储在heap中的对象很可能会在物理上改变其内存地址。这只能通过使用真正被称为Pointer的东西来实现。由于你来自C++
的世界,你知道引用限制。但这并不意味着JVM不使用引用=)。
若想获得更多信息,请参阅 Ordinary Object Pointer。
因此,由于您已经对核心JVM内存管理有简要的了解,您可以将Java Reference术语视为运行时的Pointer。
不,根本没有按引用传递。只有传值,因为真正的Java方法参数是Java Reference的副本,因此它是另一个Pointer。
因此,从语法使用的角度来看 - Java参考更接近于C++参考,但在真实的运行时世界中,它更接近于指针。由于Java不支持指针,因此引用可能看起来像是一种特殊类型的指针。但我们必须注意关键区别:使用指针时,我们可以指向任何地址(实际上是内存中的一个数字槽位)。因此,使用指针很可能会指向无效地址,然后在运行时可能会遇到意外问题。但引用类型始终将指向有效地址或将指向null。
指针只包含地址,但引用不包含地址,坦率地说,对象的地址被分配给索引或哈希码,并且将哈希码和大小写代码赋予引用变量,如果我们查看引用变量的内容,它以类名@开头,然后是一些十六进制代码。这些数字不是地址,而是索引值或哈希码。
第二点,我们不能对引用值的内容执行任何算术操作。