深入分析Java中打印对象内存地址 System.identityHashCode()方法
文章目录
- 地址是什么样子的
- toString()方法
- 重写hashCode
- identityHashCode与真正的内存地址
- 参考
地址是什么样子的
我们知道system.out.println(new XXX())可以打印出内存地址
我们看个例子:
public class Test {public static void main(String[] args) {Test t = new Test();System.out.println(t);
看下输出的结果:
Test@139a55
toString()方法
这个结果是怎么来的呢,其实是调用了Test的toString()
方法,该方法继承自Object
public class Object {public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}public native int hashCode();
看到这里,toString方法其实是打印了对象自身的hashCode,Object的hashCode() 是一个native
方法,默认返回的是内存地址
。toString方法打印不是hashCode()返回的原值,而是经过转化的16进制字符
。
重写hashCode
我们知道,hashCode()可以重写,如果重写的话,同一个类型的2个实例,hashCode
的值是相同
的,但是地址
肯定是不相同
的,此时,如果想打印出地址怎么办?这时,不能直接调用hashCode了
我们再看个例子:
public class TestMem {public static void main(String[] args) {String s1 = "hello";String s2 = "world";String s3 = "helloworld";String s4 = s1+s2;System.out.println(s3.equals(s4));System.out.println(s3==s4);System.out.println(s3.hashCode());System.out.println(s4.hashCode());System.out.println(System.identityHashCode(s3));System.out.println(System.identityHashCode(s4));}
}
结果:
true //字面值相同
false //地址不同
-1524582912 //对比2个发现hashcode相同
-1524582912
1284693
31168322
通过结果,我们发现s3和s4的字面值是相同的,但地址是不相同的,字面值相同是因为String类虽然继承了Object,但是重写了hashcode,地址不同可以通过identityHashCode
打印出来
identityHashCode与真正的内存地址
严格来说,identityHashCode()并不指向真实的地址,关于对象的真正地址,可以参见 Java 正确获取对象内存地址的方式
要在 JVM 中查找对象的内存地址,需要 Java 对象布局 ( JOL ) 工具。
首先,添加 jol-core依赖:
<dependency> <groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.10</version>
</dependency>
要在 JVM 中查找特定对象的内存地址,我们可以使用 addressOf() 方法:
String answer = "42";
System.out.println("The memory address is " + VM.current().addressOf(answer));
这将打印:
The memory address is 31864981224
HotSpot JVM 中有不同的压缩引用模式。由于这些模式,此值可能不完全准确。因此,我们不应该根据该地址执行一些本机内存操作,因为它可能会导致奇怪的内存损坏。
此外,大多数 JVM 实现中的内存地址会随着 GC 不时移动对象而发生变化。
参考
Java 正确获取对象内存地址的方式
深入分析Java中打印对象内存地址 System.identityHashCode()方法相关推荐
- Java中打印对象内存地址
Object的hashCode()默认是返回内存地址的,但是hashCode()可以重写,所以hashCode()不能代表内存地址的不同 System.identityHashCode(Object) ...
- java中什么表示打印_在java中打印对象时会发生什么
您不需要调试器就能知道发生了什么. System.out是PrintStream类型. PrintStream.println(Object)的javadoc说: Prints an Object a ...
- java判断bean是否为空_总结java中判断对象是否为空的方法
我们想要判断对象是否为空,像基本类型那样判断是不可以的, ==={} ?这样是错误的,因为这只是比较引用地址是否相同,所以可以采取下面的方法来进行判断. 1.根据for...in遍历对象,如果存在则返 ...
- Java获取对象内存地址
haseCode()方法获取并非对象内存地址 hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,获取对象散列的地址,并非实际内存地址. java直接打印对象,结果是十六进制的散列地址 ...
- java if equals_Java中判断对象是否相等的equals()方法使用教程
Object类中的equals方法用于检测一个对象是否等于另一个对象.在Object类中,这个方法判断两个对象是否具有相同的引用,如果两个对象具有相同的引用,它们一定是相等的.从这点上看,将其作为默认 ...
- java判断一个对象是否为空_Java中判断对象是否为空的方法的详解
首先来看一下工具StringUtils的判断方法: 一种是org.apache.commons.lang3包下的: 另一种是org.springframework.util包下的.这两种StringU ...
- Java中的对象和类
一. OOP中的基本概念 Java的编程语言是面向对象的,采用这种语言进行编程称为面向对象编程(Object-Oriented Programming, OOP), 它允许设计者将面向对象设计 ...
- 如何从Java中打印XML?
本文翻译自:How to pretty print XML from Java? I have a Java String that contains XML, with no line feeds ...
- JAVA中堆栈和内存分配原理
JAVA中堆栈和内存分配原理 1.栈.堆 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在 ...
最新文章
- 那些做了多少次错了多少次的题目
- python列表删除指定字典_Python:从列表中删除字典
- css实现强制不换行/自动换行/强制换行---转帖,致谢王维刚
- Shell脚本基本命令4
- Cortex-M3的工作模式和特权级别
- iOS开发之自定义弹出的键盘
- 混凝土地坪机器人_地面整平机器人:精准又高效,轻松摆“平”混凝土
- 移动端HTML5框架
- Pure Pursuit trajectory tracking and Stanley trajectory tracking总结与比较
- 存储过程与触发器的应用
- Redis学习总结(16)——Redis 集群的5种使用方式,及各自优缺点对比分析
- 程序员应该写文档吗?
- Python学习实验报告(1)
- matlab时间延迟怎么写,大家帮我看一下这个c_c方法时间延迟的程序运行结果??...
- 修改 Windows 10 主题字体
- 如何对word中不同页面设置不同页眉页脚
- Greatest Parents Ligh OJ1128
- 必知的Python 五个精彩彩蛋
- 类加载初始化顺序(nullpoint异常)
- java 简单的调用类_java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊...
热门文章
- 基础类型(Primitives)与封装类型(Wrappers)的区别
- 龙芯平台nand使用方式
- 单片机外设(ram、寄存器)地址详解
- 【多GNSS系统PPP-RTK原型系统 及性能分析】
- loops_per_jiffy的计算
- Linux中从一个目录路径中获取文件名
- Blender猫咪的头部骨骼绑定【Auto Rig Pro自我摸索0.1版本】
- “自顶向下,逐步求精”的方法
- 解决电脑出现 R6034 Runtime Error
- C# 遗传算法 排课系统优化