第07章 常用类库API_04_StringBuilder分析

转自:
作者: Betayao
出处:https://blog.csdn.net/weixin_35713860/article/details/82766350
对其中一些地方加入了自己的思考和整理,供自己和同学们学习参考。

StringBuilder

JDK官方文档里是这样说的:一个可变的字符序列。 此类提供与StringBuffer的API,但不保证同步。 此类设计用作简易替换为StringBuffer在正在使用由单个线程字符串缓冲区的地方(如通常是这种情况)。 在可能的情况下,建议使用这个类别优先于StringBuffer ,因为它在大多数实现中将更快。 简单来说:StringBuilder是StringBuffer的特殊优化版本,不考虑线程安全,效率最高。

当字符串相加操作或者改动较少的情况下,建议使用 String str="hello"这种形式;当字符串相加操作较多的情况下,建议使用StringBuilder,如果采用了多线程,则使用StringBuffer。

性能总结

  1. String对于直接相加字符串,效率很高,因为在编译器便确定了它的值,也就是说形如"I"+“love”+“java”;的字符串相加,在编译期间便被优化成了"Ilovejava"。这个可以用javap -c命令反编译生成的class文件进行验证。对于间接相加(即包含字符串引用),形如s1+s2+s3; 效率要比直接相加低,因为在编译器不会对引用变量进行优化。
  2. String、StringBuilder、StringBuffer三者的执行效率:
    StringBuilder > StringBuffer > String
    当然这个是相对的,不一定在所有情况下都是这样。比如String str = “hello”+ "world"的效率就比 StringBuilder st = new StringBuilder().append(“hello”).append(“world”)要高。

 

常见面试题

  1. 下面这段代码的输出结果是什么?
   String a = "hello2"; 
   String b = "hello" + 2;   
   System.out.println((a == b));

答:true。为什么呢?因为"hello" + 2在编译期间被优化成了"hello2",故运行期间a、b指向的是保存在常量池中的同一对象。

  1. 下面这段代码的输出结果是什么?
	String a = "hello2"; 
	String b = "hello"; 
	String c = b + 2;
	System.out.println((a == c));

 

答:false。由于有引用符号的存在,所有b + 2不会再编译期间被优化,不会吧b + 2当做字面常亮来处理,这种生成对象是保存在堆上。而a的对象是在常量池中。故a和c指向的并不是同一个对象。

  1. 下面这段代码的输出结果是什么?
	String a = "hello2";
	final String b = "hello";   
	String c = b + 2;       
	System.out.println((a == c));

答:true。对于被final修饰的变量,会在class文件常量池中保存一个副本,也就是说不会通过连接而进行访问,对final变量的访问在编译期间都会直接被替代为真实的值。那么String c = b + 2;在编译期间就会被优化成:String c = “hello” + 2。

  1. 下面这段代码输出结果为:
public class Main {
    public static void main(String[] args) {
        String a = "hello2";
        final String b = getHello();
        String c = b + 2;
        System.out.println((a == c));
    }
     
    public static String getHello() {
        return "hello";
    }
}

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

  1. 下面这段代码的输出结果是什么?
public class Main {
    public static void main(String[] args) {
        String a = "hello";
        String b =  new String("hello");
        String c =  new String("hello");
        String d = b.intern();
         
        System.out.println(a==b);
        System.out.println(b==c);
        System.out.println(b==d);
        System.out.println(a==d);
    }
}

答:false false false true。在String类中,intern方法(intern详解)是一个本地方法,在JAVA SE6之前,intern方法会在运行时常量池中查找是否存在内容相同的字符串,如果存在则返回指向该字符串的引用,如果不存在,则会将该字符串入池,并返回一个指向该字符串的引用。因此,a和d指向的是同一个对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值