java真的有指针吗?
我已经看过谷歌的答案,但我不满意。
我的逻辑:
Java
使用内存位置,它只是在幕后,你无法看到或访问它(据我所知,可能有访问它们的方式,我不知道)。
我的困惑/问题:
在像Java这样的编程语言中没有指针的目的是什么,专门为在任何系统上使用互联网而devise的,还是像c ++这样的使用指针的编程语言?
编辑
你们中的许多人都在说“保持简单”。 如果是这样的话,为什么像c++
这样的stream行编程语言仍然使用指针呢?
简单的答案是这是一个devise决定。 稍微长一点的答案是C ++中的指针只是内存操作所必需的,这不是一个适用于Java的概念(见下文)。
Java设想了一个相当系统的,面向对象的编程模型,所有基于类的types基本上都是通过一个指针来处理的,所以这个事实根本不会被用户暴露。
C ++中的原始指针在高质量,系统化和惯用的编程中也不是非常必要的。 什么原始指针允许你做(即指针算术)通常被认为是“不安全的”,所以它完全被遗漏在Java之外。
请注意,人们试图用C和C ++中的指针进行的许多事情实际上是未定义的行为。 正确使用指针会给你提供一套相当有限的选项,其中大部分可以在惯用的C ++中更好地完成。
关于指针唯一真正的用途是直接的内存操作。 由于Java不希望你这样做(事实上,它的垃圾收集内存pipe理将主动干扰并被手动内存操作破坏),因此不需要显式指针。
更新之后:最后一段(在我看来)是最引人注目的解释:在C ++中,你需要能够编写自己的内存pipe理代码(比如“allocators”)。 内存必须通过指针来处理。 所以我严格的回答是,当你实现内存pipe理时,你需要C ++中的指针,否则就不会。
在内部,一个对象的引用被实现为一个指针。 没有指针算术虽然…
C ++有指针,因为它构build为C的超集,它有指针。 C有指针,因为它是在60年代devise的。 那时计算机的内存很less,指针允许实现string,数组和parameter passing。
这是来自白皮书“Java语言环境”的摘录:
2.2.9没有更多的指针
大多数研究都认为指针是程序员将代码注入漏洞的主要function之一。 鉴于结构已经消失,数组和string是对象,指向这些结构的指针就消失了。 因此,Java没有指针数据types。 任何需要C中的数组,结构和指针的任务都可以通过声明对象和对象数组来更容易和可靠地执行。 而不是数组指针上复杂的指针操作,您可以通过它们的算术索引访问数组。 Java运行时系统检查所有数组索引以确保索引位于数组的范围内。
由于不正确的指针,您不再有悬挂的指针和内存垃圾,因为在Java中没有指针。
Java 确实有指针。 实际上,Java中的所有东西都是指针(称为引用)。
exception:int,boolean,char等
因为一切都是指针,不需要星号来改变。
首先,显而易见的问题是,Java不能保证对象在其整个生命周期中都保持在同一地址。
有效的垃圾收集器依赖于能够移动对象,并且这样做会使任何(以前)指向对象的指针无效。
其次,Java几乎有指针。 C / C ++指针不是你所想象的那样。
一个C ++指针不允许你指向一个任意的内存地址并读取它的内容。 它不允许您增加超过数组末尾的指针。
语言只是无法检测到你是否做了这些事情,没有办法赶上错误,当你这样做。 但这并不意味着它是被允许的。 这是不确定的行为,总之,可以做任何事情 。
Java几乎没有指针。 这里有一个几乎完整的清单,你可以用C ++中的指针合法地做些什么:
- 解引用它来获得指向的对象
- 重新安置它,因此它指向一个不同的对象
- 使其成为空指针
- 如果它指向一个数组,那么只要结果仍然指向同一个数组 ,或者如果两个指针都指向同一个数组,则可以执行指针算术运算,增加或减去指针。
最后一点实际上是Java中唯一不可能实现的。 它比人们通常想象的更加有限。 它不会给你一个空白的地方来创build指向任何旧地址的指针。 它不会让你“直接访问内存”。
所以Java没有指针,因为:
- 正确实施GC语言将是非常具有挑战性的,
- 它要么需要一定程度的运行时检查(以保证无效的内存访问被检测和安全地处理),要么会使Java成为一种不安全的语言,一种行为不是100%指定的语言,
- 没有多less意义,因为除了Java引用的指针外,指针只允许很less的附加function
出于同样的原因,java不具有无符号types。 该语言的devise者决定不包括他们,以保持语言“更简单”。
主要原因是可validation性。 Java字节码是这样定义的,这样加载器可以在有限的时间内决定程序是否安全执行。 指针运算不能以允许此validation的方式表示,因此已将其从语言中删除,只保留引用的赋值。
相同的限制适用于C ++ / CLI; 如果在指针上使用某些expression式,则编译器不能再使用“安全”集中的字节码来表示代码,并且如果启用了检查,组件将无法加载。
CLI和Java字节码的区别在于Java没有“不安全的”指令集,因为它是专门为Internet上的不可信代码devise的。
在Java中,所有对象都分配在堆上。 所以你总是用“指针”来引用它们(因此放弃符号),而不是C / C ++,其中静态或dynamic分配对象。
因为Java是一个简单,安全和相对简单的编程语言。 指针是Javadevise者决定不放在程序员手中的尖锐工具。
@oltarus是正确的,从某种意义上讲,Java的引用是指针,但有一个主要区别:你不能对它们进行算术运算,而你可以对指针进行算术运算。 指针运算是指针错误的主要来源,因为您可以将它们指向内存中的无效位置(例如,通过忘记初始化它们或通过逐个错误)。
更新 :C ++有指针,因为它们是C ++devise支持的那种低级系统编程所必需的。 C ++被devise成“更好的C”和替代语言,这意味着它具有实现诸如操作系统和设备驱动程序之类的所有必要的设施。 用没有指针的语言来做这件事实际上是不可能的。
C和C ++都遵循这样一种哲学:如果你要求,你几乎可以完全访问硬件,所以你几乎可以做任何你想要的东西,但是语言也不会阻止你做愚蠢的事情。 Java,OTOH通过在虚拟机沙箱中运行程序来限制对计算机的访问。
主要原因是因为指针会导致许多很难识别的错误。 在Java方式程序员的生活更容易。
对于更新后的问题:带指针的C ++比Java有更好的性能。