一、什么是String
实际上我们已经用过很多次了,但是我们今天要系统的学习一下它,因为我们以后呢,经常会用这个。
String被翻译过来是“串”的意思,在Java中是字符串的意思。就好比我们说的话,这就是一串文字。
二、String和char的区别
char可以这样去理解,就是每一个字母、好比 a,b,c 这些个单独的字母符号数字,都是char,我们也可以通过在Java中创建能看出来,char每次只能定义一个字符,不可能是俩。
String呢,就好比是将char这些个字符组成的单词,语句。
因为在我们编程的过程中,char的效率太低了,所以我们引入了String来代替char,但是这并不是表示char没有用啊!
三、如何使用
使用方式很简单,我们先创建一个类,我们叫StringTest,String测试类。
在里面我们定义一个String变量。这里有两种实例化的方式。我们一起来:
这样就定义好了,但是他们的区别是什么呢?我们下面去说,这里先不说。
接着我们输出一下这俩变量。
so easy。一下就输出出来了。
四、实例化Stirng时两种方式的区别
实例化String时,有两种方法,我们一个一个说:
首先来说(String name1 = "胖皮球";)这种的,这样的实例化方式,我们称为隐式实例化,直接赋值,一般我们编程都是这样去写,因为相比下面内种,我们可以少些很多字母。但这个不是重点。
这种实例化方式呢,是在JVM在编译Java文件生成Class文件时,将字符串"胖皮球"添加到字符串常量池中,然后,给name1一块内存,让它指向这个字符串的内存地址。
第二种方式(String name2 = new String("瘦皮球");),这样是用的构造函数,不知道大家有没有印象,我们之前学习的构造函数,在这里提现了。这种方式叫显式实例化,它呢,是在运行之后,将“瘦皮球”存放在堆内存中,然后,给name2创建一块内存,让它指向这个瘦皮球的内存地址。
所以,这两种实例化方式是不同的。我们上个图:
大概画了一个图,他们在内存中就是这个样子。
我们在操作这两种方式实例化String对象的时候,建议用直接赋值的方式,因为直接赋值的速度要大于另外一种方式。
原因是这样的:new String("瘦皮球") 实际上是做了两次操作。为啥这么说,是做了两次操作?是这样,在Java中,new出来的对象,要在内存中开辟一块空间去做存储,而,new String(“瘦皮球”),就是相当于在堆内存中给他开辟出一块空间去做存储,但是呢,String还会将这个“瘦皮球”作为常量再存放到常量池中。这么一来,就相当于做了两次操作,相比隐式实例化,它只做了一次操作,所以我们会推荐去使用这种方式去实例化String。
而且还有一点要说明,如果常量池中存在胖皮球了,如果下面再有隐式实例化,那么就不会再去创建了,而是直接指向这个常量。
五、== 与 equals
这两个东西在面试的时候会经常被问到,属于Java最基础的知识点,都是作为比较存在的。
== 是 一种运算符,而equals是方法,这是他俩的第一个不同点。
== 比较的是 运算符左面的变量和右面的变量所指向的引用指向是否相同,而equals是比较的两个值是否相同。
我们这么说大家肯定会蒙圈的,我们上代码:
我们看这段代码,你们会觉得输出什么,大部分人都会说,都是1,肯定是输出 a==b喽。我们呢,直接运行看结果。
???为啥不相等呢,原因我上面说了,== 是比较的引用,很明显一个在常量池,一个在堆,肯定不相同了。这时候我们在用一下equals:
诶,这个为啥又相同了?因为啊,equals是比较两个具体的值,也就是比较的是1 和1 这俩是不是一样的,很明显,是一样的。
我们这里给出一个图:
==比较是这样比较的
而equals是这样的:
直接看源码,相同就返回true,不一样,就返回false。
六、字符串内容
Java中,String创建的字符串内容是有不可变性。如果想改变,只能从新指向一个新地址。
我们来看代码:
看这四次输出:
第一次我们可以知道,因为两个name都是指向的同一个常量池中的东西,所以我们判断引用,他们是一样的,这个是没有问题的。
第二次,输出就是输出字符串,用来表示name已经换值了。
第三次输出我们可以看到,这俩指向的地址不一样了,因为一个是指向胖头鱼,一个是胖头鱼真香。
第四次输出,我们让其中的name指回胖头鱼这个常量,发现,他俩的引用一样了。
通过这四个说明,这个字符串常量是不可变的,而且如果变,是必须要指向一个新的地址。
东西有点多,我们分上下讲,明天更新下一讲。