如果已重新定义toString方法,如何打印对象的地址 [英] How to print the address of an object if you have redefined toString method

查看:86
本文介绍了如果已重新定义toString方法,如何打印对象的地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java的新手。现在我正在研究equals和==以及重新定义equals和toString。

I'm a newbie to Java. Now I'm studying equals and == and redefinition of equals and toString.

我想使用我已经重新定义的toString方法和默认方法继承自Object类。

I would like to use both the toString method that I have redefied and the default method that is inherited from the Object class.

我没有使用该超级修饰符来达到该方法。

I failed to use that super modificator to reach that method.

这是仅用于教育目的。如果你看一下我的代码中的评论,我想得到的更清楚。

This is for educational purposes only. What I would like to get is more clear if you will have a look at the comments in my code.

你能帮助我吗?

我的代码是:

public class EqualTest{
    public static void main(String[] args){ 
        Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
            //System.out.super.println(alice1);

        Employee alice2 = alice1;
            //System.out.super.println(alice2);

        Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
            //System.out.super.println(alice3);

        System.out.println("alice1==alice2: " + (alice1==alice2));
        System.out.println("alice1 == alice3: " + (alice1==alice3));
        System.out.println("alice1.equals(alice3): " + alice1.equals(alice3));
    }
}

class Employee{
...
    public String toString(){
        return getClass().getName() + "[name = " + name + 
            ", salary=" + salary + ", hireDay=" + hireDay + "]";
    }

}


推荐答案

严格地说,您无法在纯Java中打印对象的地址。在 Object.toString()生成的String中看起来像对象地址的数字是对象的身份哈希码。它可能与对象的当前地址有关,也可能与之无关:

Strictly speaking, you can't print the address of an object in pure Java. The number that looks like an object address in the String produced by Object.toString() is the object's "identity hashcode". It may or may not be related to the object's current address:


  • 规格不说如何计算标识哈希码编号。故意未加指定。

  • The specs do not say how the identity hashcode number is calculated. It is deliberately left unspecified.

由于该数字是哈希码,因此无法更改。因此,即使它(通常)与对象地址相关,也就是首次访问哈希码时对象的地址 。这可能与其当前地址不同,如果GC从第一次观察到对象的标识哈希码以来移动了对象,不同。

Since the number is a hashcode, it cannot change. So even though it is (typically) related to an object address, that will be the object's address at the time when the hashcode was first accessed. This could be different to its current address, and it will be different if the GC has moved the object since the first time the object's identity hashcode was observed.

在64位JVM上(具有足够大的堆大小/不使用压缩oops)地址将不适合作为 int

On a 64bit JVM (with a large enough heap size / not using compressed oops) addresses won't fit into an identity hashcode number which is returned as an int.

无论如何,获得此号码的方法是调用 System.identityHashCode(obj )

Anyhow, the way to get this number is to call System.identityHashCode(obj).

如果你真的想要一个物体的当前地址,你可以使用JNI和本机方法(以及一些抽象破坏)或使用 Unsafe 类中的方法获取它。但要注意这两种方法都是不可移植的......并且当GC运行时,它们给你的对象地址可能会中断。

If you really want an object's current address, you can get it using JNI and a native method (and some abstraction breaking), or by using methods in the Unsafe class. But beware that both of these approaches are non-portable ... and that the object addresses that they give you are liable to "break" when the GC runs.

对于怀疑者来说,这就是Java 10 javadocs对hashcode!= address所说的内容:

For the doubters, this is what the Java 10 javadocs say on the "hashcode != address" point:


(hashCode 可能会或可能不会实现对象的内存地址的某些功能某个时间点。)

强调增加。实际上,对于最近的JVM,默认行为是根本不将hashCode基于内存地址。至少从Java 7开始就是这样。

Emphasis added. Indeed, with recent JVMs, the default behavior is to NOT base the hashCode on a memory address at all. It has been that way since at least Java 7.

您可以通过包含 -XX:+ PrintFlagsFinal 来确认这一点找出 hashcode 标志的默认值,然后查看OpenJDK源代码以查看它的含义。 (代码在某些版本的vm / runtime / synchronizer.cpp文件中,但是YMMV。)

You can confirm this by including -XX:+PrintFlagsFinal to find out what the hashcode flag defaults to, and then looking at the OpenJDK source code to see what it means. (The code is in the "vm/runtime/synchronizer.cpp" file in some versions, but YMMV.)

这篇关于如果已重新定义toString方法,如何打印对象的地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆