【HeadFirst系列之HeadFirstJava】第9天之构造器与垃圾收集器:Java 对象生命周期的秘密!

Scroll Down

构造器与垃圾收集器:Java 对象生命周期的秘密!

大家好!今天我们来聊聊 Java 中的 构造器(Constructor)和 垃圾收集器(Garbage Collector)。这两个概念是 Java 对象生命周期的核心,掌握了它们,你就能更好地理解对象的创建和销毁过程。本文基于《Head First Java》第 9 章的内容,通过生动的故事和 Java 代码示例,带你轻松掌握构造器与垃圾收集器的精髓。

09-构造器与垃圾收集器-对象的前世今生-前言

1. 构造器是什么?

构造器是用于创建和初始化对象的特殊方法。它的核心作用是确保对象在创建时处于一个合法的状态。构造器的名字必须与类名相同,且没有返回类型。

构造器的特点

  • 名字与类名相同
  • 没有返回类型(连 void 也没有)。
  • 可以重载:一个类可以有多个构造器,参数列表不同。
  • 默认构造器:如果类中没有显式定义构造器,Java 会提供一个默认的无参构造器。

2. 构造器的使用

2.1 默认构造器

如果你没有定义任何构造器,Java 会提供一个默认的无参构造器。

class Dog {
    String name;
    int age;
}

public class DogTest {
    public static void main(String[] args) {
        Dog dog = new Dog(); // 使用默认构造器
        dog.name = "Buddy";
        dog.age = 3;
        System.out.println(dog.name + " is " + dog.age + " years old.");
    }
}

输出结果

Buddy is 3 years old.

2.2 自定义构造器

你可以通过自定义构造器来初始化对象。

class Dog {
    String name;
    int age;

    // 自定义构造器
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class DogTest {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy", 3); // 使用自定义构造器
        System.out.println(dog.name + " is " + dog.age + " years old.");
    }
}

输出结果

Buddy is 3 years old.

2.3 构造器重载

一个类可以有多个构造器,参数列表不同。

class Dog {
    String name;
    int age;

    // 无参构造器
    public Dog() {
        this.name = "Unknown";
        this.age = 0;
    }

    // 带参构造器
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class DogTest {
    public static void main(String[] args) {
        Dog dog1 = new Dog(); // 使用无参构造器
        Dog dog2 = new Dog("Buddy", 3); // 使用带参构造器

        System.out.println(dog1.name + " is " + dog1.age + " years old.");
        System.out.println(dog2.name + " is " + dog2.age + " years old.");
    }
}

输出结果

Unknown is 0 years old.
Buddy is 3 years old.

3. 垃圾收集器是什么?

垃圾收集器(Garbage Collector,GC)是 Java 自动内存管理的一部分,它负责回收不再使用的对象,释放内存。垃圾收集器的核心思想是自动管理内存,避免内存泄漏和手动释放内存的复杂性。

垃圾收集器的特点

  • 自动运行:程序员不需要显式调用垃圾收集器。
  • 不可预测:垃圾收集器的运行时间不确定。
  • 分代收集:Java 堆内存分为新生代和老年代,垃圾收集器采用不同的策略进行回收。

4. 垃圾收集器的工作原理

4.1 对象的生命周期

  1. 创建:通过 new 关键字创建对象。
  2. 使用:对象被引用和使用。
  3. 不可达:对象不再被任何引用指向。
  4. 回收:垃圾收集器回收不可达对象,释放内存。

4.2 垃圾收集算法

  • 标记-清除算法:标记所有可达对象,清除不可达对象。
  • 复制算法:将内存分为两块,只使用其中一块,垃圾回收时将存活对象复制到另一块。
  • 标记-整理算法:标记所有可达对象,将存活对象整理到内存的一端,清除剩余内存。

5. 代码示例:垃圾收集器实战

5.1 手动触发垃圾收集

虽然垃圾收集器是自动运行的,但我们可以通过 System.gc() 建议 JVM 进行垃圾收集。

class Garbage {
    private String name;

    public Garbage(String name) {
        this.name = name;
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println(name + " is being garbage collected.");
    }
}

public class GarbageCollectionDemo {
    public static void main(String[] args) {
        Garbage g1 = new Garbage("Object 1");
        Garbage g2 = new Garbage("Object 2");

        g1 = null; // 使 g1 不可达
        g2 = null; // 使 g2 不可达

        System.gc(); // 建议 JVM 进行垃圾收集
    }
}

输出结果

Object 1 is being garbage collected.
Object 2 is being garbage collected.

5.2 使用 finalize() 方法

finalize() 是 Object 类的一个方法,垃圾收集器在回收对象之前会调用该方法。你可以重写 finalize() 方法,在对象被回收时执行一些清理操作。

class Resource {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("Resource is being cleaned up.");
    }
}

public class FinalizeDemo {
    public static void main(String[] args) {
        Resource resource = new Resource();
        resource = null; // 使 resource 不可达
        System.gc(); // 建议 JVM 进行垃圾收集
    }
}

输出结果

Resource is being cleaned up.

6. 总结

  • 构造器:用于创建和初始化对象,确保对象在创建时处于合法状态。
  • 垃圾收集器:自动管理内存,回收不再使用的对象,避免内存泄漏。

通过本文的讲解和代码示例,相信你已经掌握了构造器和垃圾收集器的核心原理。希望你能在实际项目中灵活运用这些知识,写出更加优雅和高效的 Java 代码!


互动话题
你在项目中使用过构造器和垃圾收集器吗?遇到过哪些有趣的问题?欢迎在评论区分享你的经验!