在堆中创建对象

我们既然可以在堆中保存变量,那么也就可以保存对象,我们可以将对象保存在堆中,然后通过指针来访问它。

 

#include <iostream>

using namespace std;

int main()

{

     Human *p;

     p=new Human;

     return 0;

}

 

第一行定义了一个Human类的指针p,第二行使用new创建一块内存空间,同时又调用了Human类的默认构造函数来构造一个对象,它所占用的内存大小根据Human类对象的成员变量来决定,假如该类有两个int型成员变量,那么该对象占用为2乘以4等于8个字节。构造函数一般都是在创建对象时被自动调用,它的作用就是初始化该对象的成员数据。本行的右半部分创建一个对象完毕后,跟着将该对象的内存地址赋给左边的指针变量p

 

这两行语句也可以合并为一句。

 

#include <iostream>

using namespace std;

int main()

{

     Human *p=new Human;

     return 0;

}

 

在定义一个Human类指针p的同时将它的值初始化为新建Human类对象的内存地址。

 

我们来看实例程序。

 

#include <iostream>

using namespace std;

class Human

{

   public:

      Human(){cout<<"构造函数执行中......\n";i=999;}

private:

      int i;

};

int main()

{

     Human *p=new Human;   //使用new Human在堆中创建一个类Human的对象。

     return 0;

}

 

由于创建对象时会自动调用类的构造函数来初始化对象的成员数据,因此这里调用第6行的构造函数,调用的结果是将i初始化为999,并输出了一行汉字:“构造函数执行中......”。

 

12行的右半部分在堆中创建对象完毕后,就会返回该对象的地址,这个地址赋给了左边的指针变量p

 

在堆中创建的对象是匿名的,它没有名字,我们无法直接访问它,只能通过指针来访问它。

 

指针记录了堆中对象的地址,所以只有指针才能找到该对象。

 

本节我们主要学习如何在堆中创建一个对象,下节将学习如何删除堆中对象。

<think>好的,我现在要解决用户关于Java中new String时对象创建顺序的问题。用户想知道,当使用new String创建对象时,是先在常量池还是在中优先创建对象。我需要结合用户提供的引用内容来回答这个问题。 首先,我得回忆一下Java字符串常量池的相关知识。根据引用[1],字符串常量池在JDK1.8中是存放在中的,而不是方法区。引用[2]也提到,JDK8之后移除了永久代,常量池一直在中。所以首先确定常量池的位置是在内存里,这点很重要。 接下来,用户的问题是关于new String时的创建顺序。根据引用[1]中的例子,比如String str = new String("hello"),这里会创建两个对象吗?当常量池中不存在"hello"时,首先需要将"hello"放入常量池,然后再在中创建新的String对象。不过,这里可能存在两种情况:如果常量池中已经存在该字符串,那么直接使用;如果不存在,则先创建到常量池,再在中创建新对象。 再来看引用[1]中的第三个例子,使用char数组创建String时,如new String(new char[]{'h','e','l','l','o'}),这时候会先在堆上创建对象,然后复制数组内容。这种情况下,不会直接使用常量池中的对象,而是新建一个,除非显式地调用intern方法。 所以,当使用new String("hello")时,如果常量池没有"hello",那么首先会在常量池创建这个字符串对象,然后在中创建另一个对象,引用常量池中的对象。而如果使用new String(char数组),则直接在中创建,不会涉及常量池,除非手动intern。 总结一下,创建顺序取决于具体的创建方式。对于字面量赋值,如String s = "hello",会直接检查常量池,没有则创建。而new String("hello")时,如果常量池没有,则先创建到常量池,再在中创建新对象。因此,在new String("hello")的情况下,常量池的对象先被创建,然后才是中的对象。而对于使用char数组的情况,中的对象先创建,但此时不会自动放入常量池,除非调用intern方法。 需要确认这些步骤是否符合引用的内容。引用[1]明确指出,当使用new String("hello")时,如果常量池不存在该字符串,会创建两个对象:一个是常量池中的,一个是中的。因此,创建顺序是先常量池,后内存。而对于使用char数组的情况,则直接在中创建,不影响常量池,除非手动处理。 因此,用户的问题答案应该是:在使用new String("字面量")时,如果常量池没有该字面量,会先在常量池创建对象,然后在中创建新对象;如果是通过char数组等方式创建,则直接在中创建,不涉及常量池。所以,创建顺序取决于构造方法参数的类型。</think>在Java中,使用`new String()`创建对象时,对象创建顺序取决于参数类型和常量池的初始状态: ### 1. 使用字面量作为参数:`new String("hello")` - **若常量池不存在"hello"**: - 首先在**字符串常量池(中)**创建"hello"对象[^1][^2] - 然后在**内存**中创建新的String对象,该对象通过常量池对象初始化 ```java String s = new String("hello"); // 创建两个对象 ``` - **若常量池已存在"hello"**: - 仅需在**内存**创建新String对象,引用已有的常量池对象[^2] ### 2. 使用字符数组作为参数:`new String(char[])` - 直接在**内存**创建新对象 - **不涉及常量池**,除非显式调用`intern()`方法 ```java String s = new String(new char[]{'h','e','l','l','o'}); // 只创建一个对象 ``` ### 3. 创建顺序总结表 | 创建方式 | 常量池对象创建顺序 | 对象创建顺序 | |-----------------------------|-------------------|---------------| | `new String("字面量")` | 优先创建(若缺失) | 随后创建 | | `new String(char[])` | 不创建 | 直接创建 | | `new String("重复字面量")` | 不创建 | 直接创建 | ### 内存示意图 ``` 字符串常量池(内) 普通内存 [ "hello" ] <----引用---- [ String对象 ] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值