Java中的指针

C ++支持指针,而Java则不支持。 但是当许多程序员质疑如何在没有指针的情况下工作时,发起人开始说“受限制的指针”。所以我们可以说Java支持受限制的指针?

这里的术语非常模糊。

Java支持所谓的“引用”。 引用很像C / C ++中的指针 – 就像语言一样。 它们的行为方式与“引用”在这些语言中的工作方式不同。

C中的指针与Java中的引用之间的主要区别是:

  • 您不能在Java中执行指针运算(即,您不能从Java引用中“添加”或“减去”,您只能取消引用它或将其与另一个进行比较)。
  • 您无法将其转换为不兼容的类型:Java是强类型安全的,您不能将内存中的字节“重新解释”为其他对象。

对于指针的某些用途,这没有实际效果(例如链接列表在两种语言中的工作方式几乎相同),对于其他用途,差异非常大(C中的数组只是花哨的指针算术,在Java中它们的工作方式完全不同)。

因此,在某种程度上,Java引用可以称为“受限指针”。

维基百科将指针定义为

…一种编程语言数据类型,其值直接指向(或“指向”)另一个值

强调我的。 根据这个严格的定义,Java没有指针。

更一般的引用是指针的超类,但也包含更抽象的东西,如文件句柄甚至URL。

Java和C / C ++之间的另一个重要区别是引用是对象的索引。 而在C / C ++中,指针是内存中的地址。

在32位JVM中,它们是相同的,但是在64位JVM中它们不是。 你会注意到这个区别是,对于小于32 GB的堆大小,引用仍然是32位(即使在64位JVM中)这是因为对象是在8字节边界上分配的,所以索引可以引用到至32 GB内存(4 G * 8字节)

在64位C / C ++程序中,指针需要能够引用每个字节,即使内存分配在16字节边界上,因此它的大小为64位(从技术上讲,应该可以使其为32-位小于4 GB的内存。)

智能指针需要两个底层指针(总共16个字节)但是在gcc上,引用计数的最小分配大小是32个字节(然后你有你指向的对象的大小)总大小是32个字节每个指针+ 16个字节。 在Java中每个引用的4个字节。 (如果你有32+ GB的堆,则为8个字节)

总之,Java引用不必是实际地址,甚至不必是指针。 它肯定比智能指针小得多。

首先,您需要了解“限制指针”。 维基百科摘录:

指针的一个主要问题是,只要它们可以作为数字直接操作,就可以使它们指向未使用的地址或用于其他目的的数据。 许多语言,包括大多数函数式编程语言和最近的命令式语言,如Java,都用更不透明的引用类型替换指针,通常称为引用,它只能用于引用对象而不是作为数字操作,从而阻止了这种情况。错误类型。 数组索引作为特殊情况处理。

这意味着在Java中,您无法添加或减少指针,因为内存管理由JVM本身完成。

Java采用了参考 。 引用具有类型,就像在C中一样,并且它们是类型安全的,因为这些引用不能被解释为原始地址,并且不允许不安全的转换。

当人们说Java不支持指针时,他们正在练习新闻。 Java调用引用的内容完全对应于过去一直称为指针的内容。

Java不支持的是指针算法。 这完全是另一回事; 据我所知,C及其后代是唯一支持指针运算的类型语言。 例如,Pascal和Modula-2有“指针”,在其规范中被描述为指针,但这些指针的语义更接近于Java引用的语义; 他们不允许指针算术。

Java实际上确实有指针数学。 它附带sun.misc.Unsafe。 但是,你必须自己管理内存 – 小心。

Java有指针。 这就是为什么它有一个NullPointerException。 它只是没有指针数学。 对对象的任何引用实际上都是一个指针,这就是为什么它可以为null。 也就是说,有很多有用的编程语言都没有指针,所以任何认为指针都是编程必需的人都会对编程语言有一个非常狭隘的看法。

让我变酸:Java没有指针,因为它的设计者决定以不同方式调用它们。 事实上,他们移动堆上的所有内容,以便所有内容都由指针管理,然后,因为不再存在直接引用,取消了“。” 并将“ – >”重命名为“。”

Java语言规范有关于此事的说法:

Java语言规范§4.3.1
引用值(通常只是引用)是指向这些对象的指针 ,以及一个特殊的空引用,它指的是没有对象。

对于那些担心深入研究文档的人来说,Java的NullPointerException的存在应该是Java确实有指针的强烈迹象。

简而言之,这个问题毫无意义,因为它基于一个完全不正确的假设,即引用OP,“Java不指针” – 如上所述,这在技术上是胡说八道。

另见James Kanze的回答 。

这个答案最好被视为只是提供詹姆斯答案的必要参考。

干杯和hth。

指针只是一种可以获得回报的方式。 他们并不真正重视有效工作。 它更易于使用,您可以比使用指针更好地理解代码。 在c中的大多数源代码中,我看到了比其他东西更多的&/ * / – >如果你需要它,你会看到它。