我对使用 java 或 c++ 管理对象有疑问。
情况是,在 C++ 中,当你想创建一个动态对象时,它比创建它的块范围更有效,你必须做一个新的,你会收到一个指针。否则,如果您只想在块范围内使用此对象,则无需使用 new...
但是在 Java 中,您总是必须使用 new 创建它们,因为如果不是,则该对象为 null,您可以使用它。
这是为什么?只是它的工作原理吗?
谢谢
我能想到的最好的类比是,C++ 中的所有类型都表现得有点像 Java 中的原语。如果您在 Java 中声明一个原语,则不必使用new
,您可以立即使用该变量。但是这样一个原语,就像 C++ 中的大多数对象一样,只能在当前范围内存活。在 C++ 中,如果您希望一个对象存在于当前范围之外,您需要将这一点告诉您的编译器,因为它必须在堆而不是堆栈上分配内存。您可以使用new
. 在 Java 中,所有对象(保存原语)都分配在堆上,堆栈上的唯一数据是对堆内存的引用和原语。因此,在 Java 中,所有内存分配都是使用new
.
以上是Java中实际内存管理的简化。有关原语的堆栈/堆内存的更全面讨论,请查看此处。
这种差异是因为 Java 使用垃圾收集器进行内存管理。由于垃圾收集器会在其作用域结束时自动释放对象(并且它没有可访问的引用),因此无需使用两种不同的方法来创建对象。
你可以说 Java 中的对象自动表现得像 C++ 中的对象,它们在没有new的情况下初始化,因为你不必考虑删除它们。
基本上,这就是它的工作原理。一旦使用了新关键字,就会创建对象并将其弹出到堆上。如果您没有在方法之外引用该对象,那么垃圾收集器将自动回收该对象。我建议您阅读 Java 堆和垃圾收集的基础知识,以便更好地理解。那里有很多资源。我总是向新来的人推荐头部第一本书。
在 C++ 中,任何东西都可以在堆栈上分配(当你说
ObjectType o;
在 C++ 中。
在 Java 中,只有原语真正分配在堆栈上。对象永远不会在堆栈上(就是这样)。当你说
ObjectType o;
在 Java 中,没有分配对象,只有一个“变量”。一个变量可以引用一个对象,但目前它没有。本质上,这和说的一样
ObjectType *o = NULL
在 C++ 中。
为了实际分配一个对象供这个引用引用,你必须new
在 Java 中使用。
情况是,在 C++ 中,当你想创建一个动态对象时,它比创建它的块范围更有效,你必须做一个新的,你会收到一个指针。
C++ 中的new运算符在堆上分配空间。堆是主内存的较大部分所在的位置。如果您这样做,您有责任在使用free运算符完成后释放该空间。
否则,如果您只想在块范围内使用此对象,则无需使用 new...
当您在 C++ 中声明变量时,内存是在堆栈上分配的。堆栈是存储本地数据的地方,当函数返回时,您在执行函数时向其推送(添加)的所有内容都将自动弹出(删除)。栈通常比堆小很多,但使用它有一些好处:你不需要担心内存管理,它更快等。
但是在 Java 中,您总是必须使用 new 创建它们,因为如果不是,则该对象为 null,您可以使用它。
当您在 Java 中声明变量时,它们会再次存储在堆栈中 如您所知,您不会在原始数据类型(例如)上调用new 。int i = new int(3);
当您执行类似Object x;
声明时,这x
将是对 type 对象的引用Object
。但是,您没有为其分配值,因此引用为空(不是对象,因为没有对象)。
Java 中的new运算符,粗略地说,在堆上分配空间,调用它所调用对象的构造函数,并返回对构造对象的引用。与 C++ 的不同之处在于您不需要自己释放对象 - 有一个垃圾收集器。本质上,它的作用是监控有多少引用指向一个对象,如果它们降为零,它会自动删除该对象。
所以当你这样做时
对象 y = 新对象(); x = y;您将获得两个指向同一个对象的引用(x 和 y)。当你有这样的函数调用时
对象 foo() { 对象 y = 新对象(); 返回 y; }在您的无效酒吧(){ 对象 x = foo(); ... }
...
一部分中,bar()
您将拥有引用x
,指向在 中创建的对象foo()
。由于foo
已经返回,y
引用已被释放,因此在程序部分中将只有一个对该对象的引用...
。如果您不将x
引用复制到任何地方bar
并bar
返回,那么对该对象的引用将是 0,并且垃圾收集器会收集它(尽管不是立即)。
-斯坦