zoukankan      html  css  js  c++  java
  • Java系列2 --- 你真的知道Java的String对象么?

     ​在上一篇中说道这篇文章会说java的动态绑定机制,由于这个知识点放在继承中讲会比较合适,说以在这篇文章中先来详细的说说String对象吧。

        ​只要学过Java的同学,我们都知道Java一共有8中基本类型,但是在Java中最常用的String类型却不属于这8中基本类型中。他是Java.lang包中的一个类。但是String对象在引用传递中JVM的处理却与其他对象不同。

        ​在正式开始来讲这个String对象的时候我们首先来简单的说明下Java中的值传递和引用传递。正如很多Java说熟知的那样,Java程序员是不需要显式的使用指针的,所以在java中所有的对象都是通过引用来传递,当然基本类型还是通过值来传递。

        ​但是String类型的对象在传递中却与普通对象的引用传递略有不同。现在我们就正式的来解释下这个String对象吧。

    java文档中将String类对象称为不可变字符串。

        要理解上面这句话,首先要搞明白两个概念:字符串变量和字符串对象。

        字符串变量,是用来存放字符串变量引用的,他的值是可变的,可以根据需要存放不同的字符串对象引用的。

        字符串对象,其实我们可以理解为字符串常量,他是不可变的,一个字符串对象自从创建好后就存放在内存中     固定的位置,字符串对象中的字符也是不可以修改的。

    并且字符串对象是共享的。

        编译器可以让字符串常量共享,我们可以这样理解,在JVM中存在一个公共的字符串存储池,我们每次新建一个字符串都会保存在 这个存储池中,但是在保存前,他会把这个字符串对象的值与池中已有的字符串对象进行对比,如果没有相同的就加进去,如果有则直接引用这个已有的。

        下面的一段代码可以帮助我们理解上面的概念。

    String str1 = "hello";

    String  str2 = "hello";

    String str3 = "hell";

     

    debug结果如下:

     

        上面的代码,我们申明了三个String变量 str1str2str3, str1str2分别复制相同的字符串“hello”,debug时他们的内存id是相同的,这就说明变量str1str2引用的是同一个内存块中的内容。str3赋值不同,所以内存id也就不同。

        

        但是需要我们格外注意的是,字符串对象的共享也只限制在复制或者是初始化,如果进行拼接字符串,这种共享就不存在了,JVM会为每个拼接的字符串对象都重新创建一个存储空间,所以进行大量字符串拼接的时候,我们是禁止用String对象的。

    如下代码能说明该问题:

    String str1 = "hello";

    String str3 = str1;

    String str2 = "hello ";

    String world = "world";

    String hw = "hello world";

    String str4 = str2+world;

    String str5 = str1 + " "+"world";

    debug结果如下:

        ​上面的代码,str5是在str1的基础上拼接了“world,但是在debug中我们可以看到str的值并没有变,而str5也并不是引用的str1的内存,而是新分配了内存。

    接下来说一道我在搜房网面试时遇到的一道有关String对象的题目,来应用下上面说到的知识点:

    预测下面java代码的执行结果:

        ​    ​public static void main(String[] args) {

    String str = new String("John");

    StringBuffer sbf = new StringBuffer("John1");

    stringTest(str);

    stringBufferTest(sbf);

    System.out.println(str+"---"+sbf);

    }

    public static void stringTest(String str1){

    str1 = str1+" test";

    }

    public static void stringBufferTest(StringBuffer sbf1){

    sbf1.append(" test"); 

    }

    大家预测的结果是什么呢?是否和执行结果一致?

    下面是执行结果:

    下面我们就来详细的说明下这个执行结果的原因:

    上面的变量str和sbf都是对象的引用,在调用stringTest()和stringBufferTest()的时候都是引用传递,但是为什么String对象没有拼上“ test”字符串呢?我用下面的图来说明问题。

    这样大家应该有了解String对象了吧。如果大家发现我说的不对的地方希望大家能指出来。

    以下是我的微信公众号,技术大牛集结号,欢迎您的关注!

    给我足够的时间,我能模拟整个世界!
    给我足够的时间,我能模拟整个世界!
  • 相关阅读:
    团队第二次冲刺第六天
    团队第二次冲刺第五天
    [COCI 2017-2018-1]
    IOI2015day1. boxes
    IOI2015day2. horses
    BZOJ#4898. [Apio2017]商旅
    BZOJ#3267. KC采花
    IOI2016Day2. Messy
    IOI2016Day2. Paint
    BZOJ#1717:[Usaco2006 Dec]Milk Patterns 产奶的模式(后缀数组+单调队列)
  • 原文地址:https://www.cnblogs.com/johnhou/p/4006574.html
Copyright © 2011-2022 走看看