String的不可变性、以及和StringBuffer、StringBuilder的区别

本文详细对比了String、StringBuffer和StringBuilder的区别,包括它们的线程安全性、性能特点及应用场景,特别强调了String的不可变性及其带来的效率提升和安全性保障。

String、StringBuffer、StringBuilder的区别

1、都是final类型的,都不允许被继承
2、String是长度不可变的,StringBuffer和StringBuilder长度是可以变的
3、StringBuffer是线程安全的,StringBuilder是线程不安全的,但他们两个中的所有的方法都是相同的,StringBuffer在StringBuilder的方之上添加了synchronized修饰,保证了线程安全。
4、StringBuilder因为是线程不安全的,所以性能要好于StringBuffer
5、如果一个String类型的字符串,在编译时就可以确定是一个字符串,在编译完成之后,字符串会自动拼接成一个常量,此时String的速度比StringBuffer和StringBuilder的性能要好。

String的不可变性

为什么String是不可变的? String的不可变性,是因为jdk的开发人员在编写String类的时候就已经设定好了String类是由final修饰的,有final修饰的类,不能够被继承,所以String类中的方法不会被重写。
为什么要将String类型设置为不可变?
1、提高效率,比如一个字符串String s1 = "abc","abc"这个字符串是被放到常量池中,这个字符串就这样了,不会被修改,如果以后对这个字符串进行增删改,实际是重新将一个新的字符串放进了常量池,而"abc"这个字符串会一致存在常量池中,不会别修改,当字符串常量池中已经存在了String s1 = "abc",后,我再编写一个新的引用String s2 = "abc",这个s2引用再实际的内存当中是和s1共享"abc"这个字符串,也就是说s1 和s2引用都同时指向了"abc"这个字符串,并不会复制"abc",这样就提高了效率。而这一前提是String不可变,如果可变,那么多个引用指向同一个字符串常量,我们就可以通过一个引用改变字符串,然后其他引用就会被影响了。
2、安全,String常被用来表示URL文件路径,为了保证安全,URL路径一般是不可变的,如果可变,存在一定的安全隐患。

对于不可变的理解

1、String是被final修饰的,子类不可以被继承,不可以重写String中的方法,所以不会修改其中的方法。
2、在用‘+’号连接字符串的时候会创建新的字符串。也就是说String s1 = "abc"; s1 = s1 + "def";运算后原始String对象中的内容变了吗?没有变,只是生成了一个新的对象“abcdef”,原先的引用不在指向“abc”,而是指向了“abcdef”,s1 = s1 + "def"; 在编译阶段就对字符串进行拼接动作,只是生成了一个新的对象,等同于s="abcdef";原先的“abc”对象还在,只是没了引用。所以如果对String类型的对象进行频繁的改删,会造成大量的无用内存,尽量使用StringBuilder或StringBuffer。
3、String s = new String("Hello World");可能会创建两个对象,一个在堆内存中,一个在常量池中,如果静态常量池中有“Hello World”字符串常量对象的话,则仅仅在堆内存中创建一个新的对。如果静态区中没有“Hello World”对象,则堆内存中和静态区中都需要创建对象。 4、在java中,通过使用“+”符号来串联字符串的时候,实际底层会转化成StringBuilder实例的append()方法来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值