zoukankan      html  css  js  c++  java
  • JVM理论:(三/8)关于String、StringBuffer、StringBuilder、final

      以下是从网上整理出的资料,不同作者对某些具体描述有略微差别,有的具体描述可能会存在不准确的情况,但结论是一致的。

    一、String

      equals比较值,==比较引用,我们主要关注引用的比较。

    1、两种方式创建String的过程

    String s1="abc";
    String s2="abc";
    String s3 = new String("abc");
    System.out.println(s1==s2);
    System.out.println(s1==s3);
    
    输出结果:
    true
    false

      对于 String s1="abc"; 这种方式,如果常量池中已经存在字符串“abc”,会直接引用这个字符串,否则会创建一个“abc”字符串,所以对于s1、s2来说,引用指向的地址是一样的,返回true。相当于s1,s2 —>常量池中的字符串。(不确定的是,是不是栈中的引用直接指向常量池中的地址)

      对于 String s3 = new String("abc"); 这种方式,无论如何都会在堆中new一个String("abc")对象,当然如果常量池中没有"abc"字符串,也会先创建。相当于s3 —>堆中的对象 —>常量池中的字符串。

      s3指向的是堆中的对象,明显s1与s3指向的地址不同,所以返回false。  String s1="abc"; 在编译阶段就被确定, String s3 = new String("abc"); 在运行时才能确定。

    2、String不可变

      java.lang.String类使用了final修饰,不能被继承。Java程序中的所有字面值,即双引号括起的字符串,如"abc",都是作为String类的实例实现的。String是常量,其对象一旦构造就不能再被改变。换句话说,String对象是不可变的,每一个看起来会修改String值的方法,实际上都是创造了一个全新的String对象,以包含修改后的字符串内容,而最初的String对象则丝毫未动。

    String s = "abc";
    s = "123";
    System.out.println("s=" + s);
    
    输出结果:
    s=123

      这里看似变量s被修改了,实际上将s重新指向一个字符串“123”,而不是直接将原来的"abc"修改为"123"。

    3、String的相加运算

    String s1 = "abc";
    String s2 = "ab" + "c";
    System.out.println(s1==s2);
    
    final String  s3 = "ab";
    String s4 = s3 + "c";
    System.out.println(s1==s4);
    
    String s5 = "ab";
    String s6 = s5 + "c";
    System.out.println(s1==s6);
    
    String s7 = new String("ab") + "c";
    System.out.println(s1==s7);
    
    输出结果:
    true
    true
    false
    false

      第1,2个结果是true是因为,编译器对那些在编译期就可以确定其值的常量的运算会进行优化,因为s2+号两边是字面量,所以s2在编译期就会被优化为 String s2 = "abc";

      对于第3、4个结果,运算中存在变量,虚拟机对+的运算就会被解析为StringBuilder(或 StringBuffer)类及其 append 方法实现的,再通过toString 方法转换为字符串,所以s6相当于 s6=new StringBuffer(s5).append("c").toString(),而s6重新指向一个新的StringBuffer对象。

    //方式一
    String s = "s";
    for (int i = 0; i < 20; i++) {
        s += i;
    }
    //方式二
    StringBuffer sb = new StringBuffer("s");
    for (int i = 0; i < 20; i++) {
        sb.append(i);
    }

      结合我们平时的应用,如果用String+的方式,每循环一次,就会重新new一个StringBuffer对象,无疑造成了很多不必要的开销,而方式二会更高效一点。

    二、String,StringBuilder,StringBuffer三者的区别

      运行速度快慢为:StringBuilder > StringBuffer > String  

    String与StringBuilder、StringBuffer的区别:

      String为字符串常量,即String对象一旦创建之后该对象是不可更改的,前文中对于存在变量的String+操作,实质是new StringBuffer和.toString()操作。而StringBuilder和StringBuffer都可以直接对原对象追加、插入和删除。

    StringBuilder与StringBuffer的区别:

      StringBuilder是线程不安全的。而StringBuffer是线程安全的 ,StringBuffer中很多方法可以带有synchronized关键字。

     综上,

      String:适用于少量的字符串操作的情况

      StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况

      StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况

    三、final关键字

    1)被final修饰的类不可以被继承
    2)被final修饰的方法不可以被重写,JVM会尝试为之寻求内联。
    3)被final修饰的变量不可以被改变,在编译阶段会存入调用类的常量池中。
      
    对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
    被final修饰的变量不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的。
     
    final标记的成员变量必须在声明的同时赋值,如果在声明的时候没有赋值,那么只有一次赋值的机会,而且只能在构造方法中显式赋值,然后才能使用
    final标记的局部变量可以只声明不赋值,也只能进行一次赋值


    参考链接:  

    https://www.cnblogs.com/baihehanqiu/p/6938850.html

    http://www.cnblogs.com/avivahe/p/5747127.html

    https://segmentfault.com/a/1190000009888357

    https://blog.csdn.net/wang854837173/article/details/52439123

    https://www.cnblogs.com/qiaoyanlin/p/6877628.html

    https://www.cnblogs.com/tianyaxue/p/3145079.html

    https://blog.csdn.net/sugar_rainbow/article/details/68150249

    http://www.cnblogs.com/roy-mustango/p/4240302.html

    https://www.cnblogs.com/hithlb/p/4872373.html

    String类型相加

    https://blog.csdn.net/changjinglubeipan/article/details/78614969

    https://www.zhihu.com/question/35014775

    https://baijiahao.baidu.com/s?id=1576306750248354576&wfr=spider&for=pc

    关于string的面试题

    https://blog.csdn.net/uotail/article/details/71244606

    https://blog.csdn.net/nwpu_geeker/article/details/78701343

    StringBuffer

    https://www.cnblogs.com/su-feng/p/6659064.html

    final

    https://www.jianshu.com/p/17becea7942d

    https://www.cnblogs.com/dolphin0520/p/3736238.html

    https://www.cnblogs.com/xh0102/p/5729381.html

  • 相关阅读:
    [转]对Lucene PhraseQuery的slop的理解
    Best jQuery Plugins of 2010
    15 jQuery Plugins To Create A User Friendly Tooltip
    Lucene:基于Java的全文检索引擎简介
    9 Powerful jQuery File Upload Plugins
    Coding Best Practices Using DateTime in the .NET Framework
    Best Image Croppers ready to use for web developers
    28 jQuery Zoom Plugins Creating Stunning Image Effect
    VS2005 + VSS2005 实现团队开发、源代码管理、版本控制(转)
    禁止状态栏显示超链
  • 原文地址:https://www.cnblogs.com/zjxiang/p/9379676.html
Copyright © 2011-2022 走看看