Skip to content

对象的创建与销毁

对象的创建

使用 new 关键字

java
// 创建对象
User user = new User();

// 带参数的构造
User user2 = new User("张三", 25);

创建过程

┌─────────────────────────────────────────────────────────────┐
│                    对象创建过程                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 分配内存                                                │
│     new User() → 在堆内存中分配空间                          │
│                                                             │
│  2. 默认初始化                                              │
│     所有字段设为默认值                                        │
│     (int=0, String=null, boolean=false 等)                   │
│                                                             │
│  3. 显式初始化                                              │
│     执行属性声明时的初始化赋值                                 │
│                                                             │
│  4. 构造方法初始化                                          │
│     执行构造方法中的代码                                      │
│                                                             │
│  5. 返回引用                                                │
│     将对象地址返回给引用变量                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

示例

java
public class User {
    private String name = "默认名称";  // 显式初始化
    private int age = 0;               // 显式初始化

    public User() {
        // 构造方法初始化
        this.name = "构造函数设置";
        System.out.println("User 对象已创建");
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 使用
User user = new User();
System.out.println(user.getName());  // "构造函数设置"

构造方法

无参构造

java
public class User {
    private String name;

    // 如果没有显式定义构造方法,编译器会自动生成无参构造
    public User() {
        // 默认无参构造
    }
}

有参构造

java
public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 使用
User user = new User("张三", 25);

构造方法链

java
public class User {
    private String name;
    private int age;
    private String email;

    public User() {
        this("未知", 0);  // 调用双参构造
    }

    public User(String name) {
        this(name, 0);    // 调用双参构造
    }

    public User(String name, int age) {
        this(name, age, null);  // 调用全参构造
    }

    public User(String name, int age, String email) {
        this.name = name;
        this.age = age;
        this.email = email;
    }
}

对象的销毁

垃圾回收机制

Java 自动管理内存,不再使用的对象会被垃圾回收器回收:

java
// 创建对象
User user = new User("张三", 25);

// 解除引用
user = null;  // 之前的对象变为垃圾,等待 GC 回收

// 方法结束后,局部变量自动失去引用
void method() {
    User user = new User("李四", 30);
}  // 方法结束,user 对象变为垃圾

对象成为垃圾的条件

java
// 对象成为垃圾的条件:
// 1. 引用赋值为 null
User user = new User();
user = null;

// 2. 引用指向其他对象
User user1 = new User();
User user2 = new User();
user1 = user2;  // 第一个对象变为垃圾

// 3. 局部变量超出作用域
void method() {
    User user = new User();
}  // user 超出作用域

// 4. 匿名对象
new User();  // 立即成为垃圾

finalize 方法(已废弃)

java
public class User {
    private String name;

    @Override
    protected void finalize() throws Throwable {
        // 不要依赖此方法进行资源清理
        // 此方法已被废弃,仅用于理解对象销毁过程
        System.out.println(name + " 对象即将被回收");
        super.finalize();
    }
}

注意

finalize() 方法已被废弃,不应依赖它进行资源清理。使用 try-with-resources 或手动 close() 方法。

内存分析

内存分区

┌─────────────────────────────────────────────────────────────┐
│                      JVM 内存结构                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                    堆内存 (Heap)                     │    │
│  │                                                     │    │
│  │   ┌─────────────┐  ┌─────────────┐                 │    │
│  │   │ User 对象   │  │ String 对象 │                 │    │
│  │   │ name="张三" │  │ "Hello"    │                 │    │
│  │   │ age=25      │  │             │                 │    │
│  │   └─────────────┘  └─────────────┘                 │    │
│  │          ↑                                       │    │
│  └──────────┼───────────────────────────────────────────┘    │
│             │                                                 │
│  ┌──────────┴───────────────────────────────────────────┐    │
│  │                    栈内存 (Stack)                     │    │
│  │                                                     │    │
│  │   ┌─────────────┐  ┌─────────────┐                 │    │
│  │   │ user 引用   │  │ 局部变量    │                 │    │
│  │   │ ───────────→│  │             │                 │    │
│  │   └─────────────┘  └─────────────┘                 │    │
│  │                                                     │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                   方法区 (Method Area)               │    │
│  │                                                     │    │
│  │   类信息、常量、静态变量                              │    │
│  │                                                     │    │
│  └─────────────────────────────────────────────────────┘    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

内存分配示例

java
public class MemoryDemo {
    public static void main(String[] args) {
        // 1. 创建 User 对象
        User user = new User("张三", 25);
        // 栈:user 引用
        // 堆:User 对象

        // 2. 创建另一个引用
        User user2 = user;
        // 栈:user 和 user2 都指向同一个对象

        // 3. 解除一个引用
        user = null;
        // user 变为 null,但 user2 仍指向对象
        // 对象还未被回收

        // 4. 解除所有引用
        user2 = null;
        // 对象变为垃圾,等待 GC 回收
    }
}

对象的生命周期

创建 → 使用 → 销毁

┌─────────────────────────────────────────────────────────────┐
│                      生命周期                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  创建阶段                                                   │
│  ├── 分配内存                                               │
│  ├── 默认初始化                                             │
│  ├── 显式初始化                                             │
│  └── 构造方法初始化                                         │
│                                                             │
│  使用阶段                                                   │
│  ├── 对象被引用                                             │
│  ├── 执行方法                                               │
│  └── 访问属性                                               │
│                                                             │
│  销毁阶段                                                   │
│  ├── 对象失去所有引用                                       │
│  ├── GC 发现并标记对象                                      │
│  └── GC 回收对象内存                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

最佳实践

1. 及时释放引用

java
// ✅ GOOD
List<User> users = getUsers();
try {
    process(users);
} finally {
    users.clear();  // 释放引用
    users = null;
}

// ❌ BAD
List<User> users = getUsers();
process(users);
// users 仍然是引用,内存无法释放

2. 使用 try-with-resources

java
// ✅ GOOD
try (BufferedReader reader = new BufferedReader(
        new FileReader("file.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        process(line);
    }
}  // 自动关闭资源,对象被正确销毁

3. 避免不必要的对象创建

java
// ❌ BAD:循环中创建大量对象
for (int i = 0; i < 1000; i++) {
    String s = new String("temp");  // 每次创建新对象
}

// ✅ GOOD:复用对象
String temp = new String("temp");
for (int i = 0; i < 1000; i++) {
    // 使用 temp
}

总结

  • 对象通过 new 关键字创建
  • 创建过程:分配内存 → 默认初始化 → 显式初始化 → 构造方法
  • Java 通过垃圾回收自动管理内存
  • 理解对象生命周期有助于优化内存使用

基于 VitePress 构建