在Java中,仅在堆上创建对象有哪些优缺点?

4
在C++中,我们通常可以在堆栈上创建对象。为什么Java决定避免使用这个特性呢?

“堆栈”和“堆”在C++中并不是术语,而是实现细节。 - StoryTeller - Unslander Monica
@StoryTeller,很有趣。请问你能否更具体一些?即使你不相信完全回答问题。 - sodaluv
1
这是关于两者区别的一个解释。还要记住的是,C++中没有提到堆栈,而是提到了“自动存储期”。这意味着变量的生命周期与作用域相关联,作用域的实现方式并不重要(这里的调用堆栈是实现细节)。 - StoryTeller - Unslander Monica
1
这一点很重要,因为当 C++ 最终引入协程时,标准的措辞不会改变。作用域必须以动态方式管理,但变量的存储期仍然相同。 - StoryTeller - Unslander Monica
@StoryTeller,确实,说得好。 - sodaluv
1个回答

9

为什么Java决定避免这个功能?

这更简单。Java不会说“为什么不添加它?”Java设计者通常会等到真正需要添加一个功能时再添加。(在某些方面来说,这可能是一件好事)这意味着要成为Java专家,需要学习和理解的功能最少。

有一件事情你不必担心,那就是当你的方法返回后,你的对象会发生什么。例如,在Java中,你可以这样做:

static String str; // In Java str is a reference.

static void setS() {
    String x = "Hello";
    str = x;  // x and str are references to an object on the heap so no problem.
    // if str was now a reference to an object on the stack, 
    // you could have a corruption issue.
}

然而,使用逃逸分析,JVM可以将一个在堆上的概念对象“解压”到堆栈上,从而实际上不会发生堆分配。当前实现的缺点是没有办法强制JVM(甚至提示)去执行此操作。
好处是,在Java中你少了一件需要担心的事情。

我为什么之前没想到这个呢?完美,谢谢。 - sodaluv
3
在C ++中,您也不必担心,因为“s”将是“x”的副本。对我来说,它是否比值语义更“简单”并不清楚。它确实简化了经典的多态性。但是引用语义存在缺点。 - juanchopanza
4
我知道在Java中它们是引用。但是,“你不必担心......”并不清楚在哪种情况下您需要担心。 - juanchopanza
1
@juanchopanza 感谢您的评论,我已经更新了我的答案以澄清。 - Peter Lawrey
1
@Deduplicator 我曾经认为Java 8会有所改变,但是当你看看Java 9时,他们添加的东西并不是非常新/酷/有趣,而且Oracle投资于JavaEE的程度也不明确,它似乎正在尝试进入云计算领域。Java 9正在添加一个REPL,这可能比十多年前的Beanshell更好。 - Peter Lawrey
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接