【问题标题】:Pointer Model that Java has over C++Java 对 C++ 的指针模型
【发布时间】:2016-08-19 18:30:28
【问题描述】:

Java 和 C/C++ 之间最大的区别在于 Java 具有 消除内存覆盖可能性的指针模型 和破坏数据。

这是一本教科书的引文。我一直认为是 C++ 使用了指针而不是 Java。有人可以详细说明一下吗?

【问题讨论】:

  • 当然Java有指针;否则,您将如何获得 NullPointerExceptions?
  • 书是说Java有一个指针模型,而不是一个纯指针!英语中的模型一词意味着一种表示。您不能创建直接指针,尽管在整个实现过程中都有指针。
  • 主要区别在于,在 Java 中,不能对指针进行算术运算。
  • 这本书的意思是解释使用引用的概念,两种语言都允许你管理这个,java不允许使用指针进行算术操作......
  • Java does not have pointers(这个词在 C++ 中最少使用),它有引用。

标签: java


【解决方案1】:

我反对在描述 Java 程序时使用“指针”这个词。我总是说“对象引用”(或只是“引用”)。

在 C 或 C++ 中,指针标识进程虚拟地址空间中的位置,而虚拟地址空间基本上是一个巨大的无类型数组。给定一个指针,您可以向它添加一个偏移量,并获得一个指向数组中不同位置的指针。给定两个指针,您可以计算它们之间的偏移量。

你不能用 Java 对象引用来做任何事情。 Java 对象引用标识了堆上的 object。该对象的地址可以(并且可能确实)不时更改,但它的身份始终是唯一的。

您不能向对象引用“添加偏移量”并获得不同的对象引用。这没有任何意义。

【讨论】:

  • 我也同意你的回答。尽管它在其使用术语中说 NullPointerException。 IMO 它只是意味着没有像 C/C++ 管理它那样分配的值。在 C/C++ 中,如果您通过指针知道内存,则可以直接访问内存,但在 Java 中不能这样做。因为你永远不知道内存地址
  • 这将归结为为什么 java 工作在按值传递而不是按引用传递的概念。
  • @Acewin,按值传递与按引用传递的问题与语言是否具有 C 样式指针无关。
【解决方案2】:

它们都使用指针

在 C++ 中,指针是实际的内存地址,这意味着您可以使用一个(通过指针算法)来识别任意内存位置。

在 Java 中,指针是不透明的:知道一个的值不会给你任何关于它所指向的对象以外的任何信息。

【讨论】:

  • JVM 可能在其实现中使用指针,但“指针”在 Java 语言本身中并不是真正的概念。 (是的,我知道,“指针”这个词出现在 NullPointerException 类的名称中,但是 IMO,这只是 Java 中许多原始作者没有经过深思熟虑的名称之一。)
  • NullReferenceException 会更好。
【解决方案3】:

Java 的“参考系统”是它的指针系统。它们基本上是指针,不可能转换为不兼容的类型。它也不允许您像 C 和 C++ 那样使用指针算术。在 C++ 中,您可以通过以下方式破坏数据:

class SomeClass {
private:
    int a;
public:
    SomeClass(int a): a(a) {}
};

稍后您可以通过基本上这样做来破坏类的对象:

SomeClass victim(2);
unsigned char *hazardousPointer = (unsigned char *) &victim;
for (int i = 0; i < sizeof(SomeClass); i++)
    hazardousPointer[i] = 0;

这段代码只是允许我们违反private的访问权限并允许更改其状态(也可能是const,没关系)。之所以发生这种情况,是因为 C/C++ 指针只是内存地址,其行为与整数非常相似,但有一些限制。此外,hazardousPointer[i] 只是 *(hazardousPointer + i) 的 C/C++ 语法糖,Java 并非如此,其中数组是对象,甚至可以从方法返回并拥有自己的方法。

此外,Java 有一个垃圾收集器,它关心内存泄漏,其中 C++ 依赖于它的系统堆栈和包装器或smart pointers

【讨论】:

    【解决方案4】:

    C++ 使用指针/引用,获取和释放动态内存分配是程序员的责任。 Java 也在内部进行,但为了跟踪内存,java 使用引用计数,用最简单的术语来说就是邪恶的垃圾收集器! Java 对程序员隐藏了指针,而 C++ 并没有因此使 C++ 更强大,但也很危险。在 Java 中,您不能在堆栈上分配用户定义的对象(只有 int 等原语),但在 C++ 中,您可以使用 new 关键字在堆或堆栈上分配用户定义的对象。

    【讨论】:

    • 大多数 JVM 不使用引用计数垃圾收集器。
    • 这就是为什么我用“最简单的术语”说的意思是使用引用计数时可以理解垃圾收集。
    【解决方案5】:

    在 java 中,一切都是引用。所以你可以为一个变量创建尽可能多的别名,如果你更新其中任何一个,它将反映在所有的别名变量中。

    另一方面,C++ 既有指针又有引用。

    【讨论】:

    • 更新不会反映在原始类型的“别名变量”中。
    猜你喜欢
    • 2014-03-18
    • 2011-05-04
    • 2016-11-13
    • 1970-01-01
    • 2016-03-11
    • 2019-05-22
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多