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()方法来实现。
本文详细对比了String、StringBuffer和StringBuilder的区别,包括它们的线程安全性、性能特点及应用场景,特别强调了String的不可变性及其带来的效率提升和安全性保障。

4518

被折叠的 条评论
为什么被折叠?



