Java对象打印的是地址

在Java中,当我们通过打印一个对象时,通常会得到一个地址值。这个地址值是对象在内存中的地址,并不是对象本身的值。这个特性常常让初学者感到困惑,因此本文将详细解释这个现象,并通过代码示例来阐述。

对象和引用

在Java中,对象是通过new关键字创建的,它们存储在堆内存中。对象是实际占用内存空间的实体,它包含了对象的属性和方法。而引用则是指向对象的指针或者句柄,它指明了对象在内存中的位置。

下面是一个创建对象的示例代码:

public class Person {
    private String name;
    private int age;

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

    // getters and setters
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 25);
        System.out.println(person);
    }
}

输出结果为:

Person@6d6f6e28

我们可以看到,打印person对象时得到的是Person@6d6f6e28这样的地址值。这是因为System.out.println()方法会自动调用对象的toString()方法,而默认的toString()方法会输出对象的类名和地址值。

重写toString()方法

为了让打印对象输出更有意义的信息,我们可以重写对象的toString()方法。toString()方法是Object类中的一个方法,它可以被其他类继承和重写。

下面是重写Person类的toString()方法的示例:

public class Person {
    private String name;
    private int age;

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

    // getters and setters

    @Override
    public String toString() {
        return "Person[name=" + name + ", age=" + age + "]";
    }
}

修改后的输出结果为:

Person[name=Alice, age=25]

通过重写toString()方法,我们可以输出更加有意义的信息,便于理解和调试程序。

hashCode()equals()方法

除了toString()方法外,Object类还提供了hashCode()equals()方法。这两个方法是用来处理对象的哈希码和相等性的。

hashCode()方法返回对象的哈希码,它是一个int值。每个对象都有一个唯一的哈希码,用来标识对象在哈希表中的位置。

equals()方法用来判断两个对象是否相等。默认情况下,equals()方法比较的是两个对象的地址值是否相等。我们可以通过重写equals()方法来改变对象的相等性判断逻辑。

下面是重写Person类的hashCode()equals()方法的示例:

public class Person {
    private String name;
    private int age;

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

    // getters and setters

    @Override
    public String toString() {
        return "Person[name=" + name + ", age=" + age + "]";
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        Person person = (Person) obj;
        return age == person.age && Objects.equals(name, person.name);
    }
}

内存图示例

为了更好地理解Java对象的打印和内存分配,我们可以使用Mermaid语法中的journey来绘制一个内存图。

journey
    title Java对象的打印和内存分配过程

    section 对象创建
        Note right of JVM: Java虚拟机
        JVM -> Heap: 创建对象
        Heap -> JVM: 返回对象的引用

    section 对象打印
        JVM -> Println: 打印对象

    section 输出结果
        Println --> User: 输出地址值
        User --> JVM: 返回对象的信息