• JVM常量池与String类的理解(包含==和equals的区别)


    概述

    Java内存分析中,我们会经常听到关于“常量池”的描述,实际上常量池也分了以下三种:全局字符串常量池、class 文件常量池、运行时常量池(Runtime Constant Pool)。我们只关注常量池(Runtime Constant Pool)即可。

    String类详解

    线程有线程池来管理,而常量池就是为了来管理字符串的,所以这里必须要先熟悉String类。

    相关网址:

    Java String类(超级详细!)_长头发的程序猿的博客-CSDN博客

    常量池详解

    先看一段代码:

    1. package org.example.test;
    2. public class PoolTest {
    3. public static void main(String[] args) {
    4. String s1 = "程序猿你好!!!";
    5. String s2 = "程序猿你好!!!";
    6. String s3 = new String("程序猿你好!!!");
    7. System.out.println(s1 == s2);
    8. System.out.println(s1 == s3);
    9. System.out.println(s1.equals(s3));
    10. }
    11. }

    运行结果:

    下面我们来逐条分析: 

    1、s1 == s2

    能来研究JVM的常量池的程序猿们肯定知道”==“比的是两个对象的内存地址,那么为什么“s1 == s2"的输出结果为true呢?

    分析:

    这就是常量池的原因,常量池它本身是一种管理字符串的机制,当我们执行“String s1 = "程序猿你好!!!";”时,jvm就会在常量池中开辟一块空间来存放s1,当执行到“String s2 = "程序猿你好!!!";”时,jvm就不会为s2开辟空间了,所以说“s1 == s2"的输出结果为true。

    所以通过这个案例也能很好的理解”==“比的是两个对象的内存地址。

    2、s1 == s3

    分析:

    “String s1 = "程序猿你好!!!";”在上面也说过了,jvm会在常量池中开辟一块空间来存放s1。

    那我们主要来分析”String s3 = new String("程序猿你好!!!");“,在此之前必须要了解JVM内存区域”栈“和”堆“。

    JVM内存区域相关网址:

    JVM内存结构_长头发的程序猿的博客-CSDN博客

    ”String s3 = new String("程序猿你好!!!");“会在”栈“中开辟一块空间来放s3,在”堆“中开辟一块空间来放new出来的对象”程序猿你好!!!“。而”==“比较的内存地址,所以很明显”s1 == s3“的结果为false。

    3、s1.equals(s3)

    equlas源码:

    1. public boolean equals(Object anObject) {
    2. if (this == anObject) {
    3. return true;
    4. }
    5. if (anObject instanceof String) {
    6. String anotherString = (String)anObject;
    7. int n = value.length;
    8. if (n == anotherString.value.length) {
    9. char v1[] = value;
    10. char v2[] = anotherString.value;
    11. int i = 0;
    12. while (n-- != 0) {
    13. if (v1[i] != v2[i])
    14. return false;
    15. i++;
    16. }
    17. return true;
    18. }
    19. }
    20. return false;
    21. }

    先来分析”this == anObject“:

    this指的就是”s1.equals(s3)“中的s1,anObject指的是s3,前面也说了”==“指的是内存地址,所以“s1.equals(s2)”返回的肯定也是true,这里感兴趣的自己可以去试一下。

    再来分析”anObject instanceof String“:

    instanceof是用来判断s3是否为String,可以看出equals比较的都是String字符串。

    再看里面的内容,它先会使用”n == anotherString.value.length“来判断两个字符串的长度是否相同,再看下面的”value“和”while“这两个关键字,相信有点基础的小伙伴就可以凭借这两个关键字看出这是通过while循环比较这两个相同长度的字符的value值是否相同,由此可见,equals的主要作用就是比较两个String字符串的长度和值是否相同。

    而s1.equals(s3)中,s1(程序猿你好!!!)和s3(程序猿你好!!!)的长度和值都是相同的,所以输出结果是true。

  • 相关阅读:
    qt4 中文乱码处理
    使用Python语言制作贪吃蛇游戏,并制作成为exe可执行文件
    Java当中聊一聊String吧
    变量名命名的艺术
    ssm+微信小程序基于微信小程序的社区老人健康管理服务系统的设计与实现毕业设计源码011513
    前端工作总结214-可以不参考原型
    [NOIP1999 普及组] 导弹拦截
    嵌入式软件架构设计-建立抽象层
    gpedit.msc打不开的解决办法
    网络代理技术:保障隐私与增强安全
  • 原文地址:https://blog.csdn.net/weixin_55076626/article/details/127776457