博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
String、StringBuilder、StringBuffer区别
阅读量:5335 次
发布时间:2019-06-15

本文共 3784 字,大约阅读时间需要 12 分钟。

=====================================String=================================

★1.它在java.lang包中。String类是被final修饰的,意味着String类不能被继承。并且它的成员方法都是默认为final方法。
2.早期的JVM实现版中,被final修饰的方法会被转为内嵌调用以提升执行效率。而从Java SE5/6开始,就需要考虑用final去提升方法调用效率。
    而只有在确定不想该方法被覆盖时,才将方法设置为final。
    
3.String类是通过char数组来保存字符串的。
★4.String类中的方法,比如substring,concat,replace方法的操作,都不是在原有的字符串上进行的。而是重新生成了一个新的字符串对象。
    即,最原始的字符串并没有被改变,而是生成了一个新的字符串。
范例:
1.常见的String声明

1 public class TestString { 2  3     public static void main(String[] args) { 4         String str1 = "hello world"; 5         String str2 = new String("hello world"); 6         String str3 = "hello world"; 7         String str4 = new String("hello world"); 8          9         System.out.println(str1 == str2);10         System.out.println(str1 == str3);11         System.out.println(str2 == str4);12         13     }14     15 }

结果:    false

        true
        false
总结:
    1.class文件常量池:在class文件中有一部分来存储编译期间生成的字面常量以及符号引用,这个部分称为class文件常量。在运行期间对应着方法区的运行时常量池。
    2.上述代码中,str1和str3,都在编译期间生成了字面常量和符号引用,运行期间字面常量“hello world”被存储在运行时常量池(只保存了一份)。
        通过这种方式将String对象和引用绑定的话,JVM执行引擎会先在运行时常量池查找是否存在相同的字面常量。如果存在,就直接将引用指向已经存在的字面常量。否则在运行时常量池开辟一个空间来存储该字面常量,并将引用指向该字面常量。
    3.通过new生成对象是在堆区进行的,而在堆区进行对象生成的过程是不会去检测该对象是否已经存在。
        因此通过new来创建对象,创建出的一定是不同的对象,即使字符串的内容是相同的。
2.String.intern()

1 public class TestString { 2  3     public static void main(String[] args) { 4          5         String str1 = "hello world"; 6         String str2 = new String("hello world"); 7         String str3 = new String("hello world"); 8         String str4 = str2.intern(); 9         10         System.out.println(str1 == str2);11         System.out.println(str2 == str3);12         System.out.println(str2 == str4);13         System.out.println(str1 == str4);14         15     }16     17 }

结果:   false

         false
        false
        true
总结:在String类中,intern方法是一个本地方法,在JAVA SE6之后,intern方法会在运行时常量池中查找是否存在内容相同的字符串,如果存在则返回指向该字符串的引用,如果不存在,则会将该字符串入池,并返回一个指向该字符串的引用。因此,a和d指向的是同一个对象。
        
范例:
1.fianl修饰变量

1 public class TestFinal { 2  3     public static void main(String[] args) { 4         String a = "hello2"; 5         final String b = "hello"; 6         String c = b + 2; 7         System.out.println((a == c)); 8          9 10     }11 12 }

结果:true

总结:对于被final修饰的变量,会在class文件常量池中保存一个副本,即不会通过连接而进行访问,对final变量的访问在编译期间都会直接被替代为真实的值。
        c = b + 2,在编译期间会被优化称:c = "hello" + 2.
2.final修饰变量 + 方法调用返回值

1 public class TestFinal { 2  3     public static void main(String[] args) { 4         String a = "hello2"; 5         final String b = getHello(); 6         String c = b + 2; 7         System.out.println((a == c)); 8          9 10     }11 12     private static String getHello() {13         return "hello";14     }15 16 }

结果:false

总结:虽然将b用final修饰了,但是由于其赋值是通过方法调用返回的,那么它的值只能在运行期间确定,因此a和c指向的不是同一个对象。
范例:

1 public class TestString {2     public static void main(String[] args) {3         String str1 = "I";4         //str1 += "love"+"java";        1)5         str1 = str1+"love"+"java";      //2)6          7     }8 }

总结:1)的效率比2)的效率要高,1)中的"love"+"java"在编译期间会被优化成"lovejava",而2)中的不会被优化。

================================StringBuilder=================================
1.节约内存资源
2.在原有的字符串上操作,从始至终都只有一个对象
================================StringBuffer==================================
1.StringBuilder与StringBuffer拥有的成员属性和成员方法基本相同。区别是StringBuffer的成员方法有synchronized修饰。
    这个关键字在多线程访问时起到安全保护的作用。即StringBuffer是线程安全的。
性能:
    1.对于直接相加字符串,String效率很高;对于间接相加(包含字符串引用),形如s1+s2+s3,String效率比较低。
    2.一般情况,执行效率:StringBuilder>StringBuffer>String。比如直接相加字符串,String要比StringBuilder效率高。
    3.当字符串相加操作或改动较少的情况,建议使用String;当字符串相加操作较多的情况,建议使用StringBuilder;如果使用了多线程,建议使用StringBuffer。
注意:
    1.String str = new String("abc")创建了多少个对象
        创建了一个对象。该段代码执行过程和类的加载过程是有区别的。在类加载的过程中,在运行时常量池中创建了一个"abc"对象,而在代码执行过程中确实只创建了一个String对象。
    2.String str = new String("abc")涉及到几个String对象
        涉及了2个String对象。

转载于:https://www.cnblogs.com/ivy-xu/p/5752468.html

你可能感兴趣的文章
Week03-面向对象入门
查看>>
一个控制台程序,模拟机器人对话
查看>>
web.xml 中加载顺序
查看>>
pycharm激活地址
查看>>
hdu 1207 四柱汉诺塔
查看>>
Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(上篇——纯前端多页面)
查看>>
display:none与visible:hidden的区别
查看>>
我的PHP学习之路
查看>>
【题解】luogu p2340 奶牛会展
查看>>
对PostgreSQL的 SPI_prepare 的理解。
查看>>
解决响应式布局下兼容性的问题
查看>>
京东静态网页练习记录
查看>>
使用DBCP连接池对连接进行管理
查看>>
【洛谷】【堆+模拟】P2278 操作系统
查看>>
hdu3307 欧拉函数
查看>>
Spring Bean InitializingBean和DisposableBean实例
查看>>
Solr4.8.0源码分析(5)之查询流程分析总述
查看>>
[Windows Server]安装系统显示“缺少计算机所需的介质驱动程序”解决方案
查看>>
[容斥][dp][快速幂] Jzoj P5862 孤独
查看>>
Lucene 学习之二:数值类型的索引和范围查询分析
查看>>