Java中字符串的那些事儿
来源:互联网 发布:java bean json 编辑:程序博客网 时间:2024/06/06 02:49
字符串是java中非常常用的一种数据类型,我们通常用String类型的变量(对象)来临时存储一个字符串,关于字符串有几个值得注意的地方,下来我们一起来交流一下。
1、字符串是常量,一旦被赋值就不可以改变,但是其引用是可以改变的。
这句话什么意思呢?开始笔者就觉得很疑惑,比如说我们我们创建一个String类型的变量,例如String s = "Hello World",之后明明可以对s进行赋值操作,比如说s = "Hello Java",这样肯定是没有问题的,但这不是和上面的说法矛盾么?
那么这里我们先仔细分析一下,我们在创建s并为其赋值的时候JVM都做了些什么。需要提醒一下的是,java中的变量存储在栈内存中,而对象是存储在堆内存中,字符串则是存储在方法区的字符串常量池里。所以在执行String s = "Hello World"时JVM首先会在栈内存里开辟一个空间用来存储变量s,然后再在方法区中的字符串常量池查找池内是否存在"Hello World"这个字符串,如果存在,则把该字符串的引用地址给s;不存在的话就新创建该字符串,然后再把该字符串的引用地址给s。
而我们再次对s进行赋值的时候,比如说我们要将字符串"Hello Java"赋值给s,这个时候JVM会直接在方法区中的字符串常量池查找池内是否存在"Hello Java"这个字符串,同样的,如果存在,直接将引用地址给s,不存在创建后再将引用地址给s。所以看上去是变量s的内容变了,但实际上变化的是引用地址,而不是"Hello World"这个字符串变成了"Hello Java",不知道这样说大家能不能看明白,下面用图来说明一下,方便大家理解。
2、String s = "Hello World"和String s = new String("Hello World")是不同的。
在前面已经说了String s = "Hello World"的执行过程,这里就不再赘述,上面笔者也说了,当我们用“new”生成一个对象的时候,JVM会在堆内存中开辟一个空间来存储生成的对象,然后将该对象的引用地址给s;同时,JVM还会在字符串常量池里面寻找是否存在字符串"Hello World",这里和String s = "Hello World"执行类似的操作,但是值得注意的是,这里是将"Hello World"的引用地址给在堆中新生成的对象。
我们都知道String类“equals”和“==”的区别,“equals”比较的是字符串的内容是否相等,这个比较容易判断,我们就不多说,现在说一说“==”。如果String s1 = new String("ABC"),String s2 = new String("ABC"),那么s1 == s2的结果是true还是false?
很显然,这里是用的“new”来生成对象,那么将会在堆内存中生成开辟两个空间来存储,而这两个空间的地址肯定不一样,自然s1和s2不会相等,结果也就是false了。
3、字符串如果是两个变量相加,先开辟空间,再进行拼接;如果是两个常量相加,则先拼接,再在字符串常量池中查找拼接后的字符串是否存在。若存在,则直接返回该字符串的引用地址,否则就新创建,再返回。
举个例子来说明:
String s1 = "Hello"
String s2 = " World"
String s3 = "Hello World"
现在判断(1)s3 == s1 + s2
(2)s3 == "Hello" + " World"
分析:s1和s2是两个变量,按照上面说的,两个变量相加,先开辟空间,再进行拼接。既然开辟了空间,肯定地址不会和给s3的地址一样,所以(1)为false;而"Hello"和" World"就是两个字符串,字符串是常量,常量是先拼接,然后寻找,如果寻找不到再创建、开辟空间。所以(2)会现将"Hello"和" World"拼接为"Hello World",然后在字符串常量池中寻找有没有内容和它一样的字符串。恰好这里就有这么一个,而且这个字符串的引用地址还给了s3,所以(2)的结果自然就为true。
4、String、StringBuffer和StringBuilder的区别
(1)String的内容是不可变的,而StringBuffer和StringBuilder的内容是可变的。
(2)StringBuffer是线程安全的,所以它的效率较低;而StringBuilder是非线程安全的,效率较高。
5、在需要传入参数的方法中,基本数据类型的形式参数并不会影响实际参数;而引用数据类型的形式参数会直接影响实际参数。但是String是个例外,它的效果和基本类型一样。
- Java中字符串的那些事儿
- Java字符串那些事儿
- java中应该知道的那些事儿
- Java中关于Volatile的那些事儿
- JAVA的那些事儿
- 关于字符串的那些事儿
- Java 中AccessibleObject那些事儿
- 【java解惑】java字符串比较那些事儿
- Java那些事儿之字符串和列表
- Java String的那些事儿
- Java多线程的那些事儿
- Java编码的那些事儿
- 关于JAVA的那些事儿
- 那些年,关于 Java 的那些事儿
- javascript 的征程---字符串的那些事儿
- golang字符、字符串的那些事儿
- C语言字符串的那些事儿
- js中匿名函数的那些事儿
- 51Nod 1009 数字1的数量
- 洛谷 1514 [NOIP2010]引水入城 bfs+贪心
- 函数式编程(3):函数式编程特性
- [Android UI]Fragment的管理:getFragmentManager和getSupportFragmentManager的使用区别
- Brexit Gym
- Java中字符串的那些事儿
- Redis是可以安装成windows服务-开机自启
- 校园招聘笔试题
- Eclipse 无法自动为项目中的子项目加载Maven dependencies包而myEclipse可以
- ccf认证_学生排队 编号201703-2
- TabLayout 和ViewPager和Fragment的多页面滑动(主要实现一个水平的布局用来展示Tabs加上ViewPager实现联动效果)
- C# 异步编程3 TPL Task 异步程序开发
- ADS(Advanced Design System)2015安装破解教程,做给女朋友的,傻瓜式
- /usr/bin/ld: cannot find -lopencv_dep_cudart解决办法