当前位置: 首页 > 面试题库 >

如果已重新定义toString方法,如何打印对象的地址

王声
2023-03-14
问题内容

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

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

我未能使用该超级修饰符来实现该方法。

这仅用于教育目的。如果您可以看一下我代码中的注释,那么我想得到的内容将更加清楚。

你能在这里帮我吗?

我的代码是:

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()是对象的“身份哈希码”。它可能与对象的当前地址有关,也可能与之无关:

  • 规范 没有说明 如何计算身份哈希码号。故意将其保留为未指定。

  • 由于该数字是哈希码,因此 无法 更改。因此,即使它(通常)与对象地址有关,也将 是首次访问哈希码时的 对象地址。这可能与当前地址不同,并且自从第一次观察到对象的身份哈希码以来,如果GC已移动对象,则情况也 有所不同。

  • 在64位JVM(具有足够大的堆大小/未使用压缩的oops)上,地址将不适合作为ID返回的标识哈希码编号int

无论如何,获取此号码的方法是致电System.identityHashCode(obj)

如果您确实想要对象的当前地址,则可以使用JNI和本机方法(以及一些抽象方法)或通过使用Unsafe类中的方法来获取它。但是请注意,这两种方法都是不可移植的……并且当GC运行时,它们给您的对象地址可能会“中断”。

对于怀疑者来说,这就是Java 10 javadocs在“哈希码!=地址”点上所说的:

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

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

您可以通过包括-XX:+PrintFlagsFinal找出hashcode标志默认值的内容,然后查看OpenJDK源代码以了解其含义来确认这一点。(某些版本的代码位于“
vm / runtime / synchronizer.cpp”文件中,但某些版本为YMMV。)



 类似资料:
  • 并且(您刚才看到的是演示的一部分,下面是类的部分内容) 我真的不知道为什么它不打印字符串的东西:(所有的类(稍后将删除) }

  • 请帮助将此类型打印为格式?

  • 我正在做我的编程课介绍的作业,这是一个泡泡排序。代码可能有缺陷,但我不是在找人来解决那个问题。我的问题是,我试图打印它。我得到的条件是,该方法必须由“public static void sort(int[]array)”一行的void方法定义。因此,如果我尝试导入数组,并在main方法中使用,它将无法工作,因为我会得到一个编译器错误,说明void不适用。如果我试图将它放到main方法的循环中,它

  • 我正在寻找为json对象中的所有字段打印jsonpath的Java API。需求的第一部分是,对于给定的json对象(或字符串)- 它应该以key-value的方式打印所有属性,其中key是字段的jsonpath。 输出应该如下所示- 等等。这将用于匹配来自另一个json对象的值(我的第二个需求)。 我找到了一个APIhttps://github.com/json-path/JsonPath,它有

  • 问题内容: 我希望在下面的代码中调用newTarget.a()和newTarget.b()时应用调制后的ASM类,以便它看起来像这样 当调用应用了修改的ASM类的newTarget.a()和newTarget.b()时,如何获得以下结果? 码: 想要结果: 第一种方法 第二种方法 转换方法 第一种方法 转换方法 第二种方法 问题答案: 您正在寻找Java API 。它要求您通过参数附加Java代理

  • 问题内容: 我从mysql数据库获取ID和类别名称。 当我警告结果时,我得到: (这是对象吗?) 我如何打印这样的结果: 丹斯基 M \ u0119skie M \ u0119ski-编码错误。应该是 Męskie 。我该如何更改? 问题答案: