当前位置: 首页 > news >正文

java查看对象真实地址和哈希值的工具类

System.identityHashCode()可以查看对象未被重写的hashcode值;
VM.current().addressOf()在JVM中查找特定对象的内存地址;
有一种常见的误解,认为 JVM 中对象的内存地址是作为其默认 toString 实现的一部分表示的,例如 java.lang.Object@1b4fb997

也就是说,许多人认为这里的 1b4fb997是该特定对象的内存地址。

让我们检查一下这个假设:

Object obj = new Object();

System.out.println("Memory address: " + VM.current().addressOf(obj));
System.out.println("toString: " + obj);
System.out.println("hashCode: " + obj.hashCode());
System.out.println("hashCode: " + System.identityHashCode(obj));

输出内容:
Memory address: 31879919208
toString: java.lang.Object@1b4fb997
hashCode: 458209687
hashCode: 458209687

有趣的是, 1b4fb997 哈希码的十六进制版本,即458209687。hashCode()方法是所有 Java 对象的常用方法之一。当我们不为类声明 hashCode() 方法时,Java 将使用其身份哈希码 identityHashCode

如上所示,标识哈希码(toString中输出的后半部分)和存储器地址是不同的。


注意:

HotSpot JVM 中有不同的压缩引用模式。由于这些模式,此值可能不完全准确。因此,我们不应该根据该地址执行一些本机内存操作,因为它可能会导致奇怪的内存损坏。

此外,大多数 JVM 实现中的内存地址会随着 GC 不时移动对象而发生变化。


测试

pom.xml

        <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.16</version>
        </dependency>
public class TestMemory {

    public static void main(String[] args) {
        String s = new String("你好".getBytes(StandardCharsets.UTF_8));
        System.out.println("String类型hash值:"+s.hashCode());
        System.out.println("String类型hash值:"+System.identityHashCode(s));
        System.out.println("String类型地址值:"+VM.current().addressOf(s));
        s = "xxx";
        System.out.println("String类型修改后hash值:"+s.hashCode());
        System.out.println("String类型修改后hash值:"+System.identityHashCode(s));
        System.out.println("String类型修改后地址值:"+VM.current().addressOf(s));

        Person person = new Person();
        System.out.println("对象类型hash值:"+person.hashCode());
        System.out.println("对象类型hash值:"+System.identityHashCode(person));
        System.out.println("对象类型地址值:"+person);
        System.out.println("对象类型地址值:"+VM.current().addressOf(person));
        person.age = 2;
        System.out.println("对象类型修改后hash值:"+person.hashCode());
        System.out.println("对象类型修改后hash值:"+System.identityHashCode(person));
        System.out.println("对象类型修改后地址值:"+person);
        System.out.println("对象类型修改后地址值:"+VM.current().addressOf(person));
    }

    static  class  Person{
        int age;
    }
}

在这里插入图片描述

相关文章:

  • SOLIDWORKS直播课:解锁3DE协同设计平台的“云端结构设计角色”
  • 简单的 手写 服务器
  • 01 RocketMQ - NameServer 源码分析
  • 【CSS】数据面板
  • 记一次盖茨木马应急响应
  • 兔老大的系统设计(二)定时系统(延时队列)
  • STM32cubeMX详细教学及多个小项目合集(包含RTOS)
  • 车联网白皮书(2021.12)中国信息通信研究院
  • 【中秋征文】使用Python中秋节嫦娥投食小游戏《千里婵娟》
  • OSI网络七层模型和TCP/IP模型
  • 猿创征文|Linux环境Redis部署及最佳实践
  • 猿创征文|C++来时路 _ 重温经典之C++类和对象 | 三大特性之一 - 封装 | 腾讯面试题
  • VueJS面试常见的300道题(英文版)
  • CREO:CREO软件之零件【渲染】之对三维零件实现渲染图文教程之详细攻略
  • Java数据结构之数组的增删改查
  • [NodeJS] 关于Buffer
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • angular组件开发
  • CentOS从零开始部署Nodejs项目
  • emacs初体验
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • JavaScript中的对象个人分享
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Markdown 语法简单说明
  • MD5加密原理解析及OC版原理实现
  • Python socket服务器端、客户端传送信息
  • Python_OOP
  • Spring Cloud Feign的两种使用姿势
  • yii2中session跨域名的问题
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 基于组件的设计工作流与界面抽象
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 使用 Docker 部署 Spring Boot项目
  • 微服务框架lagom
  • 微信开放平台全网发布【失败】的几点排查方法
  • 一天一个设计模式之JS实现——适配器模式
  • nb
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #pragma multi_compile #pragma shader_feature
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • $.ajax()
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (12)Hive调优——count distinct去重优化
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (C语言)输入一个序列,判断是否为奇偶交叉数
  • (Python第六天)文件处理
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (六)激光线扫描-三维重建
  • (四)linux文件内容查看
  • (循环依赖问题)学习spring的第九天
  • (转载)从 Java 代码到 Java 堆
  • (转载)虚函数剖析
  • (状压dp)uva 10817 Headmaster's Headache