当前位置:网站首页>String类创建的对象在JVM中的内存分配和equals与==的区别

String类创建的对象在JVM中的内存分配和equals与==的区别

2022-08-09 07:24:00 哈希疯

定义:

String s1 = "uml";
String s2 = "uml";
String s3 = new String("uml");
String s4 = new String("uml");
System.out.println(s1==s2);
System.out.println(s3==s4);
System.out.println(s1.equals(s4));

判断代码输出结果

A. true false true

B. false true false

解析

该题考察的是String类创建的对象在JVM中的内存分配和equals==的区别

  • ==比较的是地址和值
  • equals比较的是值

在这里插入图片描述

  • s1==s2比较的是地址和值,由上图得知两个引用指向的是同一个地址,所以返回true.
  • s3 == s4比较的是两个new出来开辟的空间对象地址,所以值相同,但地址不同,返回false.
  • s1.equals(s3)比较的是内容,返回true
  • new创建的对象在堆区
  • 函数中的临时变量栈区
  • java中的字符串字符串常量区

此题极为不严谨,答案与具体的JVM类型和具体的JVM版本都有关系。以下分析基于广泛使用的Oracle HotSpot虚拟机:
首先,String str1 = “abc” 编译为字节码后,实际上相当于:String str1 = “abc”.intern()

对于JDK 1.6,intern()方法是这样的:如果“abc”是首次遇到,则字符串“abc”本身会被复制到字符串常量池中,且以后如果再遇到“abc”,直接返回常量池的引用。注意,JDK 1.6的常量池存在于JVM的永久代中,而对于Hotspot虚拟机的实现,永久代事实上对应java虚拟机规范中的方法区!

对于JDK 1.7,intern()方法不会对字符串实例进行复制,而只是在字符串常量池中记录首次出现的实例引用。当然,最关键的是,JDK 1.7中的字符串常量池是在堆中的!
具体请参考 “深入理解JAVA虚拟机”一书中 第 42页 和 第57页 的讨论

原网站

版权声明
本文为[哈希疯]所创,转载请带上原文链接,感谢
https://blog.csdn.net/yu57955/article/details/117626607