day04-String-StringBuffer-StringBuilder

String、StringBuffer、StringBuilder

三者联系区别

  • 都是final类,不能再被继承
  • String长度不可变,StringBuffer、Stringbuilder长度可变
  • StringBuffer是线程安全的、Stringbuilder是线程不安全的,两个类的方法都是相同的,StringBuffer在方法上加了Synchronized修饰,保证线程安全。
  • StringBuilder有更好的性能相比StringBuffer
  • 如果一个String类型的字符串,在编译时就可以确定是一个字符串常量,在编译完成之后,字符串会自动拼接成一个常量,此时String的速度比StringBuffer和StringBuilder性能好的多
  • 在java中,通过使用"+"符号来串联字符串的时候实际上底层会转成通过StringBuilder实例的append0方法来实现的。
    当我们在JDK 1.4的环境下编写代码时,对于上述这种一次性拼接多个字符串的情况,建议最好使用+号来处理。这样,当JDK 升级到1.5及以上版本时,编译器将会自动将其转换为StringBuilder来拼接字符串,从而提高字符串拼接效率。
    当然,推荐使用+号拼接字符串也仅限于在一条语句中拼接多个字符串时使用。如果分散在多条语句中拼接一个字符串,仍然建议使用StringBuffer或StringBuilder。https://www.jb51.net/article/84536.htm讲的很详细。

理解String不可变

  • final
    首先原因是因为String的不可变,如果String不是final,那么就可以继承String类,然后覆盖其方法,是的这些方法可以修改字符串,违背了String不可变性
  • 不可变原因
    提高效率:比如一个字符串Stimngs1=“abc",“abc”被放到常量池里面去了,我再Strings2 = “abc"并不会复制字符串“abc”,只会多个引用指向原来那个常量,这样就提高了效率,而这一前提是string不可变,如果可变,那么多个引用指向同一个字符串常量,我就可以通过一个引用改变字符串,然后其他引用就被影响了安全: string常被用来表示url,文件路径,如果string可变或存在安全隐患string不可变,那么他的hashcode就一-样,不用每次重新计算了
  • 不变性理解

String类是被final进行修饰的,不能被继承。
在用+号链接字符串的时候会创建新的字符串。
String s = new 5tring(“Hello world”);可能创建两个对象也可能创建一个对象。如果静态区中有"Hello world"字符串常量对象的话,则仅仅在堆中创建一个对象。 如果静态区中没有"Hello world"对象,则堆上和静态区中都需要创建对象。
在java中,通过使用"+"符号来串联字符串的时候实际上底层会转成通过StringBuilder实例的append()方法来实现。

==和equals

= = :比较引用类型比较的是地址值是否相同
equals:比较引用类型默认也是比较地址值是否相同,而String类重写了equals()方法,比较的是内容是否相同。
对于字符串变量来说,使用“ = = ” 和 “ equals() ”方法比较字符串时,其比较方法不同。
1、“ = = ”比较两个变量本身的值,即两个对象在内存中的首地址。
(java中,对象的首地址是它在内存中存放的起始地址,它后面的地址是用来存放它所包含的各个属性的地址,所以内存中会用多个内存块来存放对象的各个参数,而通过这个首地址就可以找到该对象,进而可以找到该对象的各个属性)
2、“equals()”比较字符串中所包含的内容是否相同。(String重写了Object的equals方法)
3、StringBuffer、Stringbuilder类中没有重新定义equals这个方法,因此这个方法就来自Object类,
(Object类中的equals方法是用来比较“地址”的,所以等于false)

String s = new String(“hello”)和String s = “hello”;的区别?

// 有。前者会创建2个对象,后者创建1个对象。
String s1 = new String("hello");
String s2 = "hello";
System.out.println(s1 == s2);// false
System.out.println(s1.equals(s2));// true
//相同内容不同地址

//练习
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);// false
System.out.println(s1.equals(s2));// true

String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3 == s4);// false
System.out.println(s3.equals(s4));// true

String s5 = "hello";
String s6 = "hello";
System.out.println(s5 == s6);// true
System.out.println(s5.equals(s6));// true

在这里插入图片描述

看程序写结果

字符串如果是变量相加,先开空间,在拼接。
字符串如果是常量相加,是先加,然后在常量池找,如果有就直接返回,否则,就创建。

String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
System.out.println(s3 == s1 + s2);// false,s1、s2都是变量,所以先开空间,所以一开空间就和s3不一样了
System.out.println(s3.equals((s1 + s2)));// true,内容相同

System.out.println(s3 == "hello" + "world");// true,就像前面做过的 byte=3+4
System.out.println(s3.equals("hello" + "world"));// true内容相同

// 通过反编译看源码,我们知道这里已经做好了处理。
// System.out.println(s3 == "helloworld");
// System.out.println(s3.equals("helloworld"));

10. 指出下列程序运行的结果 ( B )

public class Example {
    String str = new String("good");
    char[] ch = {'a', 'b', 'c'};

    public static void main(String args[]) {
        Example ex = new Example();
        ex.change(ex.str, ex.ch);
        System.out.print(ex.str + " and ");
        System.out.print(ex.ch);
    }

    public void change(String str, char ch[]) {
        str = "test ok";//值传递
        ch[0] = 'g';//引用传递
    }
}
----------------------------------------------------------------------------------------
A、 good and abc      B、 good and gbc 
C、 test ok and abc     D、 test ok and gbc 

其实都是引用传递,只是因为String是个特殊的final类,所以每次对String的更改都会重新创建内存地址并存储(也可能是在字符串常量池中创建内存地址并存入对应的字符串内容),但是因为这里String是作为参数传递的,在方法体内会产生新的字符串而不会对方法体外的字符串产生影响。

Java中的基本类型所使用的传递方式都为值传递,Java中的对象类型所使用的传递方式是引用传递(但字符串使用的是值传递,因为字符串是不可变的)值传递(方法内部改变,外部不会改变)引用传递,地址传递(方法内部改变,外部同步改变)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值