因为所有对象都是用“创建的”;新";在Java中,这是否意味着它们都是在堆上创建的? 这个查询的目的是比较java和C++的一个方面,它与“新”操作符有相同的关系。 现在,我知道C++中有两种方法来创建对象;有或没有“新”操作符。如果没有该运算符,则不会在堆区域中分配空间,而如果存在该运算符,则会在堆区域中分配空间

因为所有对象都是用“创建的”;新";在Java中,这是否意味着它们都是在堆上创建的? 这个查询的目的是比较java和C++的一个方面,它与“新”操作符有相同的关系。 现在,我知道C++中有两种方法来创建对象;有或没有“新”操作符。如果没有该运算符,则不会在堆区域中分配空间,而如果存在该运算符,则会在堆区域中分配空间,java,heap-memory,Java,Heap Memory,Java呢?我注意到“new”操作符用于创建每个对象。甚至使用“new”操作符创建数组。这是否意味着在Java中,对象只存在于一个地方,即堆区域 谢谢。本地基元类型和对对象类型的本地引用都会占用“堆栈”内存,当它们作为参数传递给方法时也是如此 所有对象本身都以“堆”的形式存在。是的,新操作符总是为堆上的对象分配内存。与C++不同,java中的对象不能在堆栈上创建。< P>所有java对象(即引用的所有事物)都从应用程序和应用程序程序员2的角度在HEAP1中分配。Java不支持在堆栈上显式分配对象

Java呢?我注意到“new”操作符用于创建每个对象。甚至使用“new”操作符创建数组。这是否意味着在Java中,对象只存在于一个地方,即堆区域


谢谢。

本地基元类型和对对象类型的本地引用都会占用“堆栈”内存,当它们作为参数传递给方法时也是如此


所有对象本身都以“堆”的形式存在。

是的,新操作符总是为堆上的对象分配内存。与C++不同,java中的对象不能在堆栈上创建。

< P>所有java对象(即引用的所有事物)都从应用程序和应用程序程序员2的角度在HEAP1中分配。Java不支持在堆栈上显式分配对象。对象引用可以存储在堆节点(即类或实例字段)和堆栈帧(即局部变量等)中

事实上,有几种方法可以在Java中创建一流Java对象,不涉及使用
new
关键字

  • {…}
    数组初始值设定项语法可以在数组声明中使用,而无需使用
    new
    关键字

  • 字符串文字涉及创建字符串对象(在类加载时)

  • 装箱转换(通常)将创建一个新的包装器对象,而无需显式的
    new
    或方法调用

  • 反射的
    newInstance
    和类似的方法创建对象时没有显式的
    new

  • 在幕后,Java序列化的实现使用
    Unsafe
    类中的一个特殊方法来创建对象,而不执行任何声明的构造函数

  • 您还可以使用JNI/JNAAPI在本机代码中创建Java对象

(有一个强有力的论据认为后两个“不是Java”,但无论如何它们都值得一提。字符串文本和自动装箱案例涉及到在引擎盖下使用
new
的Java代码。)


1-可以有多个堆,尽管这对应用程序是透明的


2-最新的热点JVM有一个实验性的“逃逸分析”功能,它可以确定对象是否从创建它们的上下文中“逃逸”。无法逃逸的对象可以安全地分配到堆栈上。同样,这种优化对应用程序是透明的。

在Java中,所有对象都在堆上动态分配。这与C++在堆栈或堆上可以分配对象的不同。在C++中,当使用<代码>新()/<代码>分配ABODE时,在堆上分配了BADE,否则在堆栈上分配了GABIG,如果不是全局或静态的。 在Java中,当我们只声明一个类类型的变量时,只创建一个引用(不为对象分配内存)。要将内存分配给对象,必须使用new()。因此,对象总是在堆上分配内存

示例1:给出编译错误

class Test {
    void show() {
        System.out.println("Test::show() called");
    }
}     
public class Main {
    public static void main(String[] args) {
        Test t; 
        t.show(); // Error here because t is not initialed
    }
示例2:使用
new()
分配内存使上述程序工作

class Test {
    void show() {
        System.out.println("Test::show() called");
    }
}      
public class Main {
    public static void main(String[] args) {
        Test t = new Test(); //all objects are dynamically allocated
        t.show(); // No error 
    }
}

一般来说,关键字的相同名称并不意味着相似性——有时只是相似而已。我应该选择一个答案吗?我不知道。(我删除了C++标签,使标题更精致,即使冗长。现在,如果问题是关于C++的,它仍然使用<代码>新< /Cord>,以避免“栈分配”的值类型,答案将不同,因为C不是java,就像java不是C++一样。有些对象可以在没有
new
-字符串的情况下创建,而自动装箱原语是我能想到的两个反例。@pst,这是从程序员的角度来看的,但是字符串类是不可变的,它通过内部使用“new”操作符返回一个新创建的对象。自动装箱也是如此,因为自动装箱的作用与使用“new”操作符和对应原语的包装类所做的相同。@softwarelover虚拟机规范有意不指定Java对象的存储;这是利用了我的VMs类热点,它使用转义分析来代替利用对象的堆栈分配:-)他说在任何块(例如,函数体)中都存在一些局部变量。无论它们是基本体还是分配的对象,它们都在堆栈上存在:基本体完全在堆栈上(例如,4字节
int
在堆栈上是4字节)。可以方便地将分配的对象看作堆栈上的指针;它们像指针一样占用堆栈上的空间,指针用于引用内存中指向的实际对象(使用
new
创建)。正如@oldrinb指出的,这可能并不完全是正在发生的事情,但实际上是正在发生的事情。@pickypg一个有趣的事实是JVM操作数堆栈使用32位宽度作为堆栈字<代码>双和长使用两个单词存储。堆的概念是特定于实现的,因为虚拟机规范无意限制存储选项。+ 1将相反地说“不像C++,java中没有任何方式表示您希望在堆栈上分配对象”今后很高兴地评论。虽然这是一个很好的信息,但它并没有回答“在堆栈上/在堆上”这一核心问题。添加“无论对象是否为alw”