java的String类型(二)浅谈JVM

    在java虚拟机中大致分为了栈、堆、方法区、常量池以及本地方法区等,由于String的存储涉及一二,我们便来看一下一些简单的存储机理。

    首先的存储特点:先进后出,用来存放顺序控制指令的基本数据类型,还有一些引用。值得我们注意的是(类里面的基本类型放在堆中,方法里面的基本类型在栈中),陆续我们都会讲到。

    那么今天们要讲的String就主要存储在常量池中(现在的java认为常量池是堆的一部分)。


比如我们现在定义了两个String a和b。

即String a = “qwe”;

String b = “qw”;

    那么我们就在栈中 有了a和b两个字符串的引用变量,在堆中的常量池中根据String的length给它分配足够的大空间(不可变性)。此时 “=”操作就会分别得到 “qwe”和“qw”的地址。也就是a指向了“qwe”,b指向了“qw”。

    现在我们就可以清楚地看到我们的字符串的赋值操作了,那么问题来了,是不是我们每声明一个String变量在堆中都会有一个内存空间被申请呢?

    String c = “qwe”;

    现在 我们的java虚拟机得到这段代码后,会迅速在常量池中扫描搜索“qwe”,此前的 a 已经申请了这部分空间,所以我们的 c 会直接指向“qwe”,这就实现了字符串的共享。

    如果我们重新又给了 c 一次赋值操作呢?

     c = “qwer”   

    此时也就是c的指向发生了改变,它便指向了新的内存空间区域,它从“qwe”的指向转到了“qwer”的指向。也就是它获得了新的地址。值得我们注意的是,这次仅仅只是改变了c的指向,与a无关(即便它两是同一指向)。这也是java的值传递的一个样例。

    String d = a+b;

     这个同样是根据a+b两个字符串拼接的length先分配足够大的空间,在常量池中有了一个“qweqw”的字符串,此时d指向了该字符串。

     c = c + “s”;

    涉及到自身的拼接呢?并不是在c的指向那个字符串中直接+“s”,我们已经反复强调了不变性,一个字符串的地址确定了后就不可以修改了。这个我们会拿到原来c的地址和length来重新申请一个空间得到这个字符串“qwers”,c的指向也就发生了改变。而原来的“qwer”因为没有指向被清除(如果还有别的引用指向不会被清除)。

下面我们看一下String的比较方法     

String s1 = "abc";

String s2 = "abc";

System.out.println(s1==s2);

System.out.println(s1.equals(s2));

    两个的输出结果都是“true”。但是两个的本质不同。“==”涉及到了指向问题,也就是两者如果是同一指向(记录了同一个地址),那么便是“true”,相反就是“false”。“equal()”是String类封装好的一个方法,用于比较字符串是否相等,不涉及指向问题。很简单相等就是相等。

String s3 = "abcd";

String s4 = s3.substring(0,3);

System.out.println(s1==s4);

System.out.println(s1.equals(s4));

    前者的输出结果为“false”,s4是调用了s3的一个方法 截取了s3的部分字段,而这部分字符串由new一个新空间,s4指向了新空间(堆中并非常量池)。s1与s3的指向便不相同,所以为“false”。

    后者为“true”,s1与s4代表的字段相同。

    陆续会更新String的另一种构造方法,情况会有所不同。谢谢大家。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从网上复制的,看别人的比较全面,自己搬过来,方便以后查找。原链接:https://www.cnblogs.com/...
    lxtyp阅读 1,377评论 0 9
  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 900评论 1 6
  • 前言 RTFSC (Read the fucking source code )才是生活中最重要的。我们天天就是要...
    二毛_coder阅读 477评论 1 1
  •   需要说明的一点是,这篇文章是以《深入理解Java虚拟机》第二版这本书为基础的,这里假设大家已经了解了JVM的运...
    Geeks_Liu阅读 14,129评论 5 44
  • 一、四大基本数据类型: 1、逻辑性boolean: boolean类型的数据只允许取值true or false...
    douBiWan阅读 448评论 0 0