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

概述

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

String类详解

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

相关网址:

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

常量池详解

先看一段代码:

package org.example.test;

public class PoolTest {
    public static void main(String[] args) {
        String s1 = "程序猿你好!!!";
        String s2 = "程序猿你好!!!";
        String s3 = new String("程序猿你好!!!");

        System.out.println(s1 == s2);
        System.out.println(s1 == s3);
        System.out.println(s1.equals(s3));
    }
}

运行结果:

下面我们来逐条分析: 

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源码:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

先来分析”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。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值