关于java:帮你看清-Java-字符串的世界

2次阅读

共计 3723 个字符,预计需要花费 10 分钟才能阅读完成。

这是蜗牛互联网的第 113 期原创。

作者 | 红色蜗牛

起源 | 蜗牛互联网(ID: woniu_internet)

转载请分割受权(微信 ID: 919201148)

本文纲要:

前言

在上一篇文章 Java 根本类型的各种运算,你真的理解了么?里,咱们学习了 Java 的根本类型和他们之间的运算。Java 根本类型堪称是 Java 世界里应用最频繁的数据类型了。除此之外,有种数据类型你也肯定会遇到,它在 Java 世界里应用也相当频繁。它就是字符串!

听到字符串,你是不是想起了字符这种类型。不过在 Java 里,字符和字符串是两种不同的类型。

字符串的定义与模式

字符类型你应该比拟相熟,通过关键词 char 来申明一个字符。

值只能是 一个英文字符 或者 一个中文字符 或者是 Unicode 编码 ,用 单引号 包住。如下:

`// char 用 ascii 字符赋值 `
`char charWithAscii = '.';`
`char charWithZh = '牛';`
`char a = '\u0041';// 值为 A`

而字符串,顾名思义,就是多个字符连贯而成的串。通过关键词 String  来申明一个字符串。

值能够是 null 或者 空字符串 或者 单字符串 或者 多字符串 ,用 双引号 包住。如下:

`// null 字符串,未指定地址 `
`String nullStr = null;`
`// 空字符串,蕴含 0 个字符 `
`String  blankStr = "";`
`// 蕴含一个字符 `
`String oneCharStr = "A";`
`// 蕴含多个字符,打印 蜗牛 666 A`
`String multiCharStr = "蜗牛 666 \u0041";`

你会发现字符串的值能够是 null,因为字符串类型 String 是援用类型,值为 null,就阐明值不存在,也就是这个变量不指向任何对象。这也是它和根本类型 char 的区别所在。

那作为援用类型,String 就能够通过 new 的形式申明,比方:

`String newStr = new String("蜗牛 666");`

另外,你也会发现字符串比字符存储了更丰盛的数据,实际上,一个字符串能够存储 0 到任意多个字符。只有把数据内容用双引号包起来就好。

不过,如果你的数据内容自身就有双引号,会产生什么呢?

没错,连编译都过不去!编译器会提醒你字符串非法行尾,因为编译器判断的时候,会把两头引号当成字符串结尾,导致第三个引号开始的字符串语法出错。

那此时就要用到转义字符了,这个 case 里能够通过反斜杠 \ 本义两头的引号。

`String str = "蜗牛 666\"";`

这样就不会报错了。

字符串的存储形式

咱们晓得,程序在运行时,会针对不同类型的变量数据做运算,最终输入后果。那其实运算过程中的变量数据都是存在栈里边,依据栈先进后出的特点,实现程序的运行逻辑。而对 Java 这种面向对象编程的语言,对象的信息就没放栈里边,而存到了堆里边,栈只存对象的援用地址。

另外,有些数据要求是不可变的,Java 会调配一块常量池进去。

比方 String 的场景。

`String str1 = "蜗牛 666";`
`String str2 = "蜗牛 666";`
`String newStr1 = new String("蜗牛 666");`
`String newStr2 = new String("蜗牛 666");`

str1 和 str2 就存储在常量池中。而常量池中的数据只有一份,因而 str1 和 str2 其实是指向同一块内存空间。

newStr1 和 newStr2 是通过 new 语法创立的对象,在创立的过程中,Java 会先去常量池中查找是否已有 蜗牛 666 对象,如果没有则在常量池中创立一个 蜗牛 666 对象,而后在堆中创立一个 蜗牛 666 的拷贝对象。

所以 new String("xxx"); 这行代码会产生几个对象?

答案是一个或两个。如果常量池中原来没有 xxx,就是两个。如果有就是一个。

字符串的特点

字符串最大的特点就是 不可变性。前边也有提过,字符串在常量池会有一份,常量这个信息就阐明字符串具备不可变性了。

咱们看下实例,你猜下以下程序会输入什么:

`String strChange = "蜗牛 666";`
`System.out.println(strChange);`
`strChange = "蜗牛 888";`
`System.out.println(strChange);`

都是 蜗牛 666?因为字符串不可变嘛

事实上不是:

` 蜗牛 666`
` 蜗牛 888`

难道 蜗牛 666 被改成 蜗牛 888 了?

实际上不是,蜗牛 666蜗牛 888 都在,只是 strChange 的指向变了。

程序在执行 String strChange = "蜗牛 666"; 时,JVM 虚拟机先在常量池创立字符串 蜗牛 666,而后把变量 strChange 指向它。

而后在执行 strChange = "蜗牛 888"; 时,JVM 虚拟机先在常量池创立字符串 蜗牛 888,而后把变量 strChange指向它。

所以你会发现,刚开始的字符串 蜗牛 666 还在,只是变量 strChange 不再指向它了。

因而,字符串的不可变个性,是指 字符串内容不可变

另外,字符串的不可变个性,也带来了两个益处。

一个是 String 对象能够缓存哈希码。在 String 类的源码中,你能够看到这么一个属性。

`/** Cache the hash code for the string */`
`private int hash; // Default to 0`

hash 的值是基于字符串的每个字符计算得出。那字符串的不可变个性,就能保障 hash 的唯一性,因而能够缓存起来,被频繁应用。这也是性能优化的一种伎俩。

另外一个就是字符串的不可变个性保障了很多场景下的平安。

很多 Java 类库都会抉择 String 作为参数,像文件门路 path 这些。如果 String 会常常扭转,那就有各种安全隐患。

字符串的罕用场景

比拟

和根本类型相比,字符串也有比拟的能力。比方上面的比拟形式。

`String equalChar = "蜗牛";`
`String euqalCharCompare = "蜗牛";`
`System.out.println(equalChar == euqalCharCompare);`

间接常量定义的形式,没有问题,会输入 true。但如果通过 new 的形式定义那就容易出错了,比方以下的代码,你晓得输入什么么?

`String equalMethod = new String("蜗牛");`
`String euqalMethodCompare = new String("蜗牛");`
`System.out.println(equalMethod == euqalMethodCompare);`

会输入 false,而这是不合乎咱们预期的。为什么会这样呢?

因为 == 对于援用类型而言,比拟的是援用的地址。而上边两个字符串都是 new 进去的新对象。援用地址天然不同。

那如果想只比拟内容怎么做呢?能够应用 Java String 自带的 equals 办法!

`System.out.println(equalMethod.equals(euqalMethodCompare));`

此时就能失常输入 true 了。

拼接

最简略的拼接就是用 + 连接符,比方以下代码。

`/**`
 `* 字符串连贯 `
 `*`
 `* @author 蜗牛 `
 `* @from 公众号:蜗牛互联网 `
 `*/`
`public class StringConnect {`
 `public static void main(String[] args) {`
 `String name = "蜗牛";`
 `String age = "18";`
 `String profile = name + " " + age;`
 `System.out.println(profile);`
 `}`
`}`

运行代码会输入:

` 蜗牛 18`

咱们能够通过反编译看下,这段代码产生了什么,输出命令:

`javap -c StringConnect`

咱们看到有如下输入:

你会发现,加号连接符实际上是 Java 编译器的优化,底层是用了 StringBuilder 这个类,它的 append 办法就起了拼接的成果。

如果拼接的字符串数量无限,绝对固定,倡议用加号连接符,这样一行代码搞定!

如果拼接的字符串有相干的逻辑,比方循环拼接,字符串数量不太固定,那倡议用 StringBuilder 这个工具类。

另外,StringBuilder 是线程不平安的,如果你是多线程开发环境,为了保障程序不出错,能够用它的兄弟类 StringBuffer,这个类办法和 StringBuilder 统一,只是减少了线程平安的能力。

总结

本文围绕着字符串介绍了它的定义和模式,另外它的存储形式如果理解不清晰的话,在一些逻辑判断上容易出错。字符串的不可变个性,既晋升了它的拜访性能,又保障了安全性。字符串最罕用的场景,就是比拟和拼接,当然还有很多其余应用场景,咱们后边能够再细讲。


我是蜗牛,大厂程序员,专一技术原创和个人成长,正在互联网上摸爬滚打。欢送关注 我,和蜗牛一起成长,咱们一起牛~ 下期见!

正文完
 0