JavaSE之深度剖析String类


提示:以下是本篇文章正文内容,Java系列学习将会持续更新

一、初步认识

  1. String不是基本数据类型;而是Java中的一种包装类,重写了equals()方法。
  2. String类不可被继承,String对象是可不变的,因为被 final 修饰。
  3. String实例的字符串都是同过 char[] 储存的。
    在这里插入图片描述
  4. String 类中每一个看起来会修改 String 值的方法,实际上都是创建了一个全新的 String对象,以包含修改后的字符串内容。而最初的 String 对象则丝毫未动 。
    在这里插入图片描述
    回到目录…

二、创建字符串的三种方式

  1. 直接赋值:只会开辟一块堆内存空间,并且该字符串对象可以自动保存在对象池中以供下次使用。
String str = "Welcome to java";
//推荐这种方式,只产生一个对象,节省空间
  1. 构造方法:会开辟两块堆内存空间,不会自动保存在对象池中。
String str = new String("Welcome to java");
//会产生两个对象,产生垃圾空间

在这里插入图片描述
这种方式的缺点:
 a. 如果使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存将成为垃圾空间(字符串常量 “hello” 也是一个匿名对象, 用了一次之后就不再使用了, 就成为垃圾空间, 会被 JVM 自动回收掉).
 b. 字符串共享问题. 同一个字符串可能会被存储多次, 比较浪费空间.

// 可以手工入池,intern();不会创建垃圾空间
String str1 = new String("hello").intern();
String str2 = "hello";
System.out.println(str1 == str2);  //输出:true
  1. 通过char[]数组创建字符串
char[] data = {'h','e','l','l','o'};
String str = new String(data);

回到目录…

三、字符串常量池

String类的设计使用了共享设计模式

在JVM底层实际上会自动维护一个字符串常量池:

  • 如果现在采用了直接赋值的模式进行String类的对象实例化操作,那么该实例化对象(字符串内容)将自动保存到这个对象池之中。
  • 如果下次继续使用直接赋值的模式声明String类对象,此时对象池之中如若有指定内容,将直接进行引用。如若没有,则开辟新的字符串对象而后将其保存在对象池之中以供下次使用。

回到目录…

四、理解字符串的不可变性

String str = "hello";
str = "world";
System.out.println(str);  //输出:world

在这里插入图片描述
回到目录…

五、通过反射破坏String类

通过反射强行破坏String类的封装,获取value数组进行改变。
听听就行了:

import java.lang.reflect.Field;
public class Test {
    public static void main(String[] args) throws Exception{

        String str = "hello";
        //通过反射获取String类中的value数组
        Field field = String.class.getDeclaredField("value");
        //value的private定义取消掉
        field.setAccessible(true);
        //获取到str对象内部的value数组
        char[] value = (char[]) field.get(str);
        value[0] = 'H';
        System.out.println(str);   //输出:Hello
    }
}

回到目录…

六、与StringBuilder的关系

为了方便字符串的修改,引入这两个类,它俩大部分功能是相同的。
 StringBuffer : 线程安全
 StringBuilder : 线程不安全,但是更快
实际上它们与String类没有一点关系,没有血缘关系。

出现字符串拼接 “+” 时,JVM会自动把字符串转换成StringBuilder类型的,调用其中的append()方法扩展字符串,避免产生过多的垃圾空间。

回到目录…

七、equals 和 == 的判断

equals()方法是判断两个对象的内容是否相同,而 == 是判断是否为同一个对象。

String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2)); // true
System.out.println(str1 == str2); // false
String str3 = "world";
String str4 = new String("world");
System.out.println(str3.equals(str4)); // true
System.out.println(str3 == str4); // false
String str5 = "张三";
String str6 = "张三";
System.out.println(str5.equals(str6)); // true
System.out.println(str5 == str6); // true

回到目录…


总结:
提示:这里对文章进行总结:
以上就是今天的学习内容,本文是JavaSE的学习,深度剖析String类,学习字符串创建的方式,字符串的不可变性,以及字符串常量池。之后的学习内容将持续更新!!!

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只咸鱼。。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值