对String类的深入理解
String类:
String类相信大家对这个类并不陌生,这就是我们熟悉的字符串类型,但是我们一开始只知道它是用来定义字符串的,并不知道它的底层原理,这里我们就来简单的分析一下String的底层原理,首先我们来看一下String类的体系图:
这里我们可以看出String实现了三个接口其中的Serializable接口说明我们String类型是可以序列化的,那么什么是序列化呢?这里可以简单的了解一下,具体的内容在I/O流中我们会详细的介绍,实现该接口的对象可以将信息以流的方式传输到自己的磁盘内,实现了Comparable接口说明我们的字符串是可以相互比较的。
字符串的初始化方式有两种一种是直接赋值 : String 变量名 = ".....",还有一种是调用构造器进行初始化:String 变量名 = new String("....")待会我们会解释一下这俩个方法的差异,首先我们来了解一下String类的一些基本概念,首先String类它是final的,简单来讲它是无法修改的,但是你在对它重新赋值的时候你会发现,它的值确实被修改了,待会我们会分析它被修改的原因。
首先我们来分析一下String俩个创建方法的区别,我们通过代码来观察一下:
public class String01 {
public static void main(String[] args) {
String name1 = "孙悟空";
String name2 = new String("孙悟空");
System.out.println(name1 == name2);
}
}
他们定义名字都是“孙悟空”为什么他们不是同一个对象,这里给大家画个示意图:
当我们在创建字符串常量的时候,系统会先在常量池中找一下看看有没有,如果没有就直接创建一个,当我们使用String name1 = “孙悟空”的时候就会在常量池中直接创建,然后直接指向。但是你使用new String()的时候系统会现在堆里面开辟一个空间name2指向该空间,然后通过0xxx22来找常量池中的“孙悟空”,所以name1和name2所指向的对象不同虽然结果一样,但是内在的对象创建方式是截然不同的。
再来解释一下String不能被修改这个问题:
你在执行String name1 = “孙悟空”;这个代码的时候name1会直接指向常量池中的“孙悟空”,当你再执行name1 = “唐三藏”的时候你会发现name1的内容变成了唐三藏,不是说孙悟空这个值被修改成了唐三藏,而是系统在常量池中创建了“唐三藏”这个常量,原本指向“孙悟空”的线被切断了,指向了“唐三藏”,“孙悟空”这个变量还是存储在常量池当中的,所以我们才说String是不可变的。