05String类

String类底层维护了一个final修饰的char数组(jdk8,jdk9后变成了byte数组),所以String一旦创建就不能更改,属于字符串常量,任何字符串常量都是一个String类的匿名对象。

==和equals()的区别

== 比较基本类型数据的时候比较的是值的大小,比较引用数据类型的时候比较的是对象的地址。

equals()是Object类中的方法,Object中equals方法的实现还是依靠==,所以比较的是两个对象的地址。但是String类对equals()进行了重写,它会先通过 == 判断两个对象的地址是否一致,一致的话就返回true,如果不一致,就进行字符串内容的对比,如果内容相同就返回true。

直接赋值实例化和构造器实例化的区别

因为String类底层是用数组来存储字符串的,所以受数组长度的限制,字符串不可变。

不管是哪种实例化方式,它们的引用都是存储在栈中的。如果是编译期创建好的就存储在常量池中,如果是运行期间创建好的就存储在堆(动态常量池)中。对于equals相等的字符串,在常量池中永远只有一份,在堆中可以有多份。

  • 直接赋值实例化

    String str = “ABC”;

    编译期已经创建好了,字符串就存储在常量池中。如果常量池中已存在“ABC”,就让str直接引用,如果不存在,就在常量池中创建一个。

  • 构造器实例化

    String str2 = new String(“ABC”);

    运行期间创建字符串对象,因为是new出来的,所以字符串对象会存储在堆中。当new了一个“ABC”时,会先去常量池看看是否已有,如果没有就在常量池中创建一个“ABC”对象,然后在堆中创建一个常量池中“ABC”的拷贝对象,返回堆中“ABC”对象的地址。

  • String intern()

    str1 = str.intern();

    str.intern()会返回一个内容与str相同,但是来源于字符串池的字符串。当调用intern()方法时,如果池中已经包含了该字符串,那么返回池中的这个字符串,否则,在池中创建该字符串并返回。

  • 做点小题:

    String str1 = new String("ABC");
    String str2 = new String("ABC");
    System.out.println(str1 == str2)//false
        
    String str3 = "ABC";
    String str4 = "ABC";
    String str5 = "A" + "BC";//在定义str5对象时采用的全部是字符串常量,编译器就会把它们当做一个整体,放到常量池中。
    System.out.println(str3 == str4)//true
    System.out.println(str3 == str5)//true
        
    String a = "ABC";
    String b = "A";
    String c = b + "BC";
    System.out.println(a == c)//false
    //a和b都是字符串常量所以在编译期都已经确定了,会存放在常量池。c中有个变量b,变量的内容是运行时分配的,所以会造成内容不确定的问题,会保存在堆中。因此结果是false。
    
    String d = new String("d");
    String d1 = "d";
    System.out.println(d1 == d.intern())//true
    

字符串修改分析

字符串的对象内容理论上是可以修改的,它所做的修改并不是修改具体的堆内存,而是创建新的堆内存并引用,之前的堆内存就成了垃圾。所以要避免频繁的进行字符串的修改,那样会造成大量的垃圾。对于频繁修改的需求,可以借助StringBuffer或StringBuilder类。

String的方法

String有length(),数组的是length属性。String方法太多了,用了查文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值