Java有指针吗?
如果Java没有指针,那么new
关键字在Java中做什么?
正如指出的,Java有参考。 这些有什么不同?
- 你不能对这些进行算术或其他的操作
- 他们不指向包含对象的内存 (即它们不是指向别的名字的指针)。 JVM可以随意在虚拟机内存中移动对象,而且很有可能在垃圾收集过程中执行。 然而,参考文献仍然指出这个对象,尽pipe它在记忆中移动。
所以他们不像C ++引用(直接指向一个对象)。 也许更好的名字是处理 。
Java没有指针; Java有参考。
这是一个很好的观点,但是一个指针有额外的操作,你可能(或不可以)通常使用; 由于这些操作可能是不安全的,因此缺less这些操作。
例如,如果您使用指针索引数组的第一个元素,如下所示:
int squares[] = {1, 4, 9, 16, 25, 36, 49}; int* intPointer = squares;
您可能需要取消引用指针并获取值“1”,但您也可以:
intPointer++
当你这样做的时候,当你取消引用指针时,你会得到值“4”。 一秒
intPointer++;
将被解除引用,给你的价值“9”。 这是因为++操作将指针向前移动一个“单位”在内存中。
这个问题来自C / C ++types检查系统的弱点(C ++必须保持与C的兼容性,所以它允许相同的问题)。 指针将地址存储在内存中,++操作将相应数量的字节添加到地址中。 在很多系统上,int一个int增加了四个字节,但是如果指针是一个char指针++的话,它应该只添加一个字节。 请注意,由于指针的基础数据types是内存中的地址,因此以下内容是合法的(但不推荐):
char* charPointer = squares; charPointer++; void* voidPointer = squares; voidPointer++;
由于指针是内存中的地址,因此它们可能(正确)表示计算机中的任何内存位,但只有在底层数据符合指针的types和alignment时才能正确解除引用。 对于不被大量代码pipe理的指针来保证它们的安全,这意味着您可能会丢弃所需信息的数据types(或alignment方式),并且解除引用可能会导致灾难。 试图用自定义代码解决这个问题往往会使一个指针变得非常慢,以致于您注意到了性能问题,并且会在自定义“指针pipe理”代码中添加错误。
Java方面通过返回一个引用来解决所有这些问题。 参考不涉及内存中的任何位置; Java维护一个内部的“指针”表的引用。 该表采用引用并返回与其关联的数据,无论数据驻留在内存中的哪个位置。 这会减慢代码的执行速度,因为每个“取消引用”都会执行两次查找,参考表中有一次查找,机器内存中有一次查找。
Java使用引用的一大优点是内存可以被移动而不会破坏可能的指针地址。 在C程序中,如果将数据移动到新的内存位置,则很难知道程序的其他部分是否有指向数据的指针。 在移动内存之后,应该废除一个陈旧的指针,程序将访问损坏的数据,并且通常会导致崩溃。
在正在运行的程序中移动内存的能力允许程序轻松地回收内存。 任何不需要大块内存的程序都可以释放未使用的内存,但是这会在使用过的内存块之间产生未使用内存的内存空洞。 内部计算机使用相当大的内存页面。 如果一个稀疏使用的内存页面可能有less量使用的位移动到另一个页面,则可以释放一页内存。 这增加了数据到内存的密度,提高了caching的性能。 有时这会转化为性能改善,这可能相当戏剧性。
Java的垃圾收集器通过临时阻止访问一组引用的数据来利用引用。 在访问阻塞期间,它会移动数据(压缩它)。 阻塞之后,对地址表的引用具有新的存储器地址。 由于代码的“function”层始终不知道地址,因此该操作不会中断正在运行的Java程序。
Java具有指针,用于存储对数据的引用。 Java中Objecttypes的所有variables都是这个意义上的指针。
但是,Java语言不允许对指针值进行算术运算,就像你能用C这样的语言进行操作一样。
new
(大致)如下:
- find一个连续的堆空间,等于你正在创build的类的实例大小,再加上一些簿记空间
- 零表示空间并将其从免费列表中删除
- 运行构造函数
- 返回一个引用(不是一个指针,像其他职位已经解释的)到创build的实例。
Java有参考。 所有对象都通过引用其实例来访问。 使用new
创build一个新的实例,该实例返回对该对象的引用。
Java引用不像C中的指针,你不能在组成对象的原始内存中“查看底层”。
Java没有指针。 在Java中,运算符“new”用于引用variables。
显示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); } }
Java中的new
返回对新创build对象的引用 。
新的回报参考。 它与指针有一些相似之处(如果你传递给函数,引用通过,和指针一样),但没有指针算术。
Java不支持或不允许指针。 (或者更恰当地说,Java不支持可被程序员访问和/或修改的指针。)Java不允许指针,因为这样做会允许Java小程序在Java执行环境和主机之间破坏防火墙。 (请记住,一个指针可以被赋予内存中的任何地址 – 甚至可能在Java运行时系统之外的地址。
Java 确实有指针,这些指针在名称“ reference ”下已知。
当人们说“Java没有指针”时,他们通常将指针的概念与C和C派生语言中指针的具体实现和能力相混淆。
尤其是:
- Java引用不能设置为任意地址 。 也不能(标准)Pascal或Fortran指针。
- Java引用不能被设置为指向一个variables 。 也不能(标准)Pascal指针。
- Java引用不支持指针运算 。 帕斯卡也没有Fortran指针
- Java引用无法指向对象的某些部分 (如数组的第三个元素)。 帕斯卡指针也不行。
另外,与普遍的看法相反, 指针不一定是地址 。 指针通常作为一个地址来实现,但是不需要这样做,即使在C或C ++中也是如此。
在java中我们只遇到了THIS指针,它用来引用同一类的variables。 new运算符用作对象的引用。