new
关键字是用来做什么的?正如所指出的,Java有引用。 它们与其他引用有何不同?
因此,它们不像C++引用(直接指向对象)。 也许更好的名称应该是句柄。
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程序。void*
没有指针算术运算或隐式的int*
到char*
转换。 - T.C.Java有指针,它们是存储内存数据引用的变量。在这个意义上,Java中所有的Object类型的变量都是指针。
然而,与像C语言一样的语言不同,Java语言不允许对指针值进行算术运算。
new
大致执行以下步骤:
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);
}
}
p2
有一个值并且不是null
,这证明Java确实没有指针,否则p2
将指向p1
并且也是null
。 - user1191027Java有引用。所有对象都是通过引用它们的实例来访问的。您可以使用new
创建一个新实例,该实例返回对对象的引用。
Java引用不像C中的指针,您不能“查看”组成对象的原始内存。
char
的指针(类型转换不是指针的固有属性),(2)char
保证直接映射到机器字节(这显然不是指针的属性),以及(3)C和C++具有指针算术运算(再次强调,这不是通用指针特性,而是这些语言的特定功能)。 - celtschknew
在 Java 中返回一个指向新创建对象的引用。
new 返回引用。它与指针有一些相似之处(如果传递给函数,引用会被传递,就像指针一样),但没有指针算术运算。
new
操作符与变量有什么本质关系吗?例如,如果我运行 System.out.println(new String("hello"));
,其中使用了 new
,那么“引用变量”在哪里? - Chai T. Rex
outb(0x08,0x378);
或旧的peek / poke在“小型CPU”上一样。 - SF.