Java有指针吗?

时间:2010-04-13 12:12:55

标签: java pointers

如果Java没有指针,那么new关键字在Java中的作用是什么?

12 个答案:

答案 0 :(得分:47)

正如所指出的,Java有参考。这些有何不同?

  1. 您无法对这些
  2. 执行算术运算或其他此类操作
  3. 他们不指向包含对象的内存(即它们不是另一个名称的指针)。 JVM可以自由地在VM内存中移动对象,并且很可能在垃圾收集期间执行。然而,引用仍指向该对象,尽管它在内存中移动。
  4. 所以它们不像C ++引用(直接指向一个对象)。或许更好的名称是 handle

答案 1 :(得分:37)

Java没有指针; Java有参考。

这是一个很好的观点,但指针有额外的操作,你可能(或可能不)通常使用;引用缺少这些操作,因为操作可能不安全。

例如,如果使用指针索引数组的第一个元素,如下所示:

int squares[] = {1, 4, 9, 16, 25, 36, 49};
int* intPointer = squares;

您可能想要取消引用指针并获取值“1”,但您也可以:

intPointer++

并且在您执行此操作后,当您取消引用指针时,您将获得值“4”。第二个

intPointer++;
当取消引用时,

将为您提供值“9”。这是因为++操作将指针在内存中向前移动一个“单位”。

问题来自于C / C ++类型检查系统的缺点(C ++必须保持与C的兼容性,因此它允许相同的问题)。指针在内存中存储一​​个地址,++操作将适当数量的字节添加到地址中。在许多系统上,使用int添加四个字节,但如果指针是一个char指针,那么它应该只添加一个字节。请注意,由于指针的基础数据类型是内存中的地址,因此以下内容是合法的(但不推荐):

char* charPointer = squares;
charPointer++;

void* voidPointer = squares;
voidPointer++;

由于指针是内存中的地址,它们可能(正确地)表示计算机中的任何内存位,但只有当底层数据与指针的类型和对齐方式匹配时,它们才会被正确解除引用。对于不是由大量代码管理以使其安全的指针,这意味着您可能会偏离所需信息的数据类型(或对齐),并且取消引用可能以灾难结束。尝试使用自定义代码修复此问题往往会导致一个指针严重减慢,以至于您发现性能问题,并且它为在自定义“指针管理”代码中添加错误打开了大门。

Java端通过返回引用来解决所有这些问题。引用不是指存储器中的任何位置; Java维护一个内部的“指针引用”表。此表获取引用并返回与其关联的数据,无论数据驻留在内存中的何处。这会减慢代码执行速度,因为每次“解除引用”都会进行两次查找,参考表中有一次查找,机器内存中有一次查找。

使用引用的Java的一大优点是可以移动内存而不会破坏可能的指针地址。在C程序中,如果将数据移动到新的存储器位置,则很难知道程序的其他部分是否具有指向数据的指针。如果在移动内存后取消引用陈旧指针,程序将访问损坏的数据,通常崩溃将是缺点。

在正在运行的程序中移动内存的功能允许程序轻松回收内存。任何不需要内存块的程序都可以释放未使用的内存,但这会在使用过的内存块之间创建未使用内存的内存空洞。内部计算机使用非常大的内存页面。如果稀疏使用的存储器页面可能将少量使用的位移入另一页面,则可以释放一页存储器。这增加了数据到内存的密度,提高了缓存性能。有时这会转化为性能改进,这可能会非常引人注目。

Java的垃圾收集器通过临时阻止对一组引用的数据访问来利用引用的优势。在访问阻塞期间,它会移动数据(压缩它)。在阻塞之后,对地址表的引用具有新的存储器地址。由于代码的“功能”层从不知道地址,因此该操作不会破坏正在运行的Java程序。

答案 2 :(得分:12)

Java在存储对数据的引用的变量意义上有指针。 Java中Object类型的所有变量都是这个意义上的指针。

但是,Java语言不允许对指针值进行算术运算,就像你能用C语言那样。

答案 3 :(得分:7)

new(大致)执行以下操作:

  1. 找到一个连续的堆内存空闲块,其等于您正在创建的类的实例大小,以及一些用于簿记的空间
  2. Zero说太空&将其从免费列表中删除
  3. 运行构造函数
  4. 向创建的实例返回引用(不是指针,正如其他帖子所解释的那样)。

答案 4 :(得分:3)

java.lang.NullPointerException

人们在采访中告诉我“java没有指针”。 我通常给他们一些java代码并让他们解释一下,这段代码中发生了什么:

public class TestPointers {

    public static void main(String args[]) {
        Object p1, p2;
        p1 = new Object();
        p2 = p1;
        p1 = null;
        System.out.println(p2);
    }
}

答案 5 :(得分:3)

Java 确实有指针,这些指针名称为" 引用"。

当人们说" Java没有指针"时,他们通常会将指针的概念与C和C派生语言中指针的具体实现和能力混淆。

特别是:

  • Java引用无法设置为任意地址。也不能(标准)Pascal或Fortran指针。
  • Java引用不能设置为指向变量。也不能(标准)Pascal指针。
  • Java引用不支持指针算法。 Pascal也不是Fortran指针
  • Java引用不能指向对象的某些部分(就像数组的第三个元素一样)。帕斯卡指针也不能。

此外,与普遍看法相反,指针不一定地址。指针通常被实现为地址,但是没有要求这样做,即使在C或C ++中也是如此。

答案 6 :(得分:1)

Java有参考。通过引用其实例来访问所有对象。您可以使用new创建一个新实例,该实例返回对该对象的引用。

Java引用不像C中的指针,你不能在组成对象的原始内存中“查看引擎”。

答案 7 :(得分:0)

Java中的

new会向新创建的对象返回 引用

答案 8 :(得分:0)

新的退货参考。它与指针有一些相似之处(如果传递给函数,则传递引用,与指针相同),但没有指针算术。

答案 9 :(得分:-1)

Java没有指针。运算符“new”用于java中的引用变量。

答案 10 :(得分:-1)

Java不支持或允许指针。 (或者更确切地说,Java不支持程序员可以访问和/或修改的指针。)Java不允许指针,因为这样做会允许Java applet突破Java执行环境和主机之间的防火墙。 (请记住,指针可以在内存中给出任何地址 - 甚至可能在Java运行时系统之外的地址。)

答案 11 :(得分:-3)

在java中我们只遇到THIS指针,它用于引用同一类的变量。 operator new用作对象的引用。