Java作业笔记2:String 和 StringBuffer的区别

目录

一、String深入:编译期和运行期

1.简单阐述:

2.代码例子:

(1)System.identityHashCode()查询对象的引用地址:

二、String和StringBuffer的区别:

1.可变与不可变:

2.初始化方式:

3.字符串修改方式:

4.equals()方法:

5.线程安全性:

三、文章参考:


一、String深入:编译期和运行期

1.简单阐述:

        在编译时,如果碰到了String s = "hello"; 这样的赋值方式,就是字面量形式赋值,编译时就直接编译成 String s = "hello"; ,然后拿到内存中时就按照上述所说的直接赋值的那种方式去赋值,str3 = "abc" + "d"其实就等同于字面量赋值(即等同于str3 = "abcd")。但是,如果是str2这种赋值方式String str2 = str + "d"; ,虽然str在上面已经定义了,但是在编译时认为str仍是一个引用类型变量,所以此时就会把str2认为是以new String()方式来创建的,等来到内存中呢,就按照new String()这种方式去创建str2,自然堆内存中就会开辟空间,然后创建对象,接着再把空间的地址值返回给str2。所以str1和str2并没有指向同一个对象,地址值自然不同,这同时也解释了提出的问题。

2.代码例子:

(1)System.identityHashCode()查询对象的引用地址:

        System.identityHashCode()方法间接查询真实的地址

        似乎String.hashCode()方法返回的是处理过的地址???

String str = "abc";//在常量池中创建abc
String str1 = "abcd";//在常量池中创建abcd
String str2 = str+"d";//拼接字符串,此时会在堆中新建一个abcd的对象,因为str2编译之前是未知的
String str4 = str1;//由于并没有拼接运算,直接将str1的引用地址传递给str
String str3 = "abc"+"d";//拼接之后str3还是abcd,所以还是会指向字符串常量池的内存地址
System.out.println(str1==str2);//false
System.out.println(str1==str4);//True
System.out.println(str1==str3);//true
public class StringBy
 
{
 
    public static void main(String[] args){
 
    //情况一
 
    String a = "a2";
 
    String a2 = "a"+2;
 
    //在编译期值是确定的就是a2。只有编译期变量a与变量a2值相等他们才相等
 
    System.out.println(a==a2);
 
    //情况二
 
    String b = "b2";
 
    int bb = 2;
 
    String b2="b"+bb;
 
   //在编译期变量b2的值不是确定的,因为bb是变量,变量在运行期才能确定值.所以b与b2不等
 
    System.out.println(b==b2);
 
    //情况三
 
    String c="c2";
 
    final int cc=2;
 
    String c2="c"+cc;//在编译期c2的值是确定的,因为cc是个常量,值为2
 
    System.out.println(c==c2);
 
    //情况四
 
    String d="d2";
 
    final int dd=getZ();
 
    String d2="d"+dd;
 
    //在编译器d2的值是不确定的,因为dd还没有确定,因为dd的值是靠方法返回来的,但是方法的结果是在            
    //运行期才能得到的
 
    System.out.println(d==d2);//(对于两个对象,==的作用是比较他们的地址。)
 
    }
 
    public static int getZ(){
 
        return 2;
 
    }
 
}

二、String和StringBuffer的区别:

1.可变与不可变:

String:长度固定

StringBuffer:长度可变

StringBuilder:长度可变

2.初始化方式:

String:直接赋值和new开辟

StringBuffer:new开辟

StringBuilder:new开辟

3.字符串修改方式:

String:由于长度不可改变,修改时相当于创建StringBuffer对象并调用append()方法,最后toString()将引用地址返回给String,堆中将会产生无引用指向的垃圾冗余,冗余到一定程度,JVM会启用垃圾清理,造成性能下降。

StringBuffer:直接在该字符串后边加,不改变引用。

4.equals()方法:

String中的equals方法进行了重写:比较的是字符串的内容

StringBuffer中未对equals方法进行重写:比较的是引用地址

5.线程安全性:

StringBuffer与StringBuilder都提供了一系列插入、追加、改变字符串里的字符序列的方法,它们的用法基本相同,只是StringBuilder是线程不安全的,StringBuffer是线程安全的,。如果只是在单线程中使用字符串缓冲区,则StringBuilder的效率会高些,但是当多线程访问时,最好使用StringBuffer。

三、文章参考:

(1条消息) Java:String类型为什么可以直接赋值?使用new String赋值不可以吗?_@阿证1024的博客-CSDN博客_string为什么可以直接赋值

深入理解String、StringBuffer和StringBuilder类的区别 - 腾讯云开发者社区-腾讯云 (tencent.com)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值