写了那么久的String字符串,你可能根本不懂它!

简介: String str和new String()有什么区别?这个问题之前在面试中有被问到过一次,当时面试结束后也写了自己关于这个题目的理解,不过最近在看Effect Java的时候发现书中也提到了关于String的用法,刚好就放到一起聊一下。

网络异常,图片无法展示
|


本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看


(一)引言


String str和new String()有什么区别?这个问题之前在面试中有被问到过一次,当时面试结束后也写了自己关于这个题目的理解,不过最近在看Effect Java的时候发现书中也提到了关于String的用法,刚好就放到一起聊一下。


(二)关于String字符串


String应该是Java中最常用的一个对象,他不是八种基本数据类型的其中之一,但是我随便翻了一下项目代码,用String定义的变量超过百分之八十。


publicfinalclassStringimplementsjava.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */privatefinalcharvalue[];
/** Cache the hash code for the string */privateinthash; // Default to 0}

关于String的几个基本知识点在String类的源码定义中就能看到:


1、在JDK8中,String实例的值是通过char数据存储的。(JDK9时,String实例的存储由char变成了byte数组,原因是使用byte数组可以减少一半的内存)


2、String类被final修饰,因此String不能被继承,value变量被final修饰,因此String实例不能被修改


3、String类实现了Serializable, Comparable, CharSequence接口


(三)关于字符串常量池


字符串常量池是虚拟机中的内容,但是接下来的几个问题需要用到,就简单了解下。为了让String字符串可以复用,Java虚拟机中设置了一种叫做字符串常量池的东西。


Java为了避免产生大量的String对象,设计了一个字符串常量池。工作原理是这样的,创建一个字符串时,JVM首先为检查字符串常量池中是否有值相等的字符串,如果有,则不再创建,直接返回该字符串的引用地址,若没有,则创建,然后放到字符串常量池中,并返回新创建的字符串的引用地址。因此看下面这段代码:


Strings1="abc";
Strings2="abc";
System.out.println(s1==s2);  //返回true

返回的结果就是true,因为指向了同一个对象。


关于字符串常量池的位置,在不同版本的JDK中有所不同:


JDK1.7之前字符串常量池属于运行时常量池的一部分,存放在方法区


JDK1.7之后字符串常量池被从方法区拿到了堆中


(四)String str和new String()有什么区别


回到开始的问题,String str和new String()有什么区别?区别在于,String str创建的字符串保存在字符串常量池中,并且可复用。new String()创建的字符串按照最标准的对象创建方式,生成在堆中,并且一个new String会在堆中创建一个对象。下面这张图应该可以把这个流程讲清楚。


网络异常,图片无法展示
|


s1==s2返回true,s1==s3返回false。


(五)new String()方法创建了几个对象


又是个好问题,这道题的答案是一个或者两个。


写一段代码:


publicclasstest {
publicstaticvoidmain(String[] args) {
Strings1=newString("ab");
    }
}

编译后通过javap -v test.class查看字节码:


网络异常,图片无法展示
|


1、在常量池中创建了ab对象,位置在#3


网络异常,图片无法展示
|


2、在堆中创建了ab对象


这样的情况下创建了两个对象,一个在常量池中,一个在堆中。


再写一段代码:

publicclasstest {
publicstaticvoidmain(String[] args) {
Strings1="ab";
Strings2=newString("ab");
    }
}

同样的方式查看字节码:


网络异常,图片无法展示
|


首先s1="ab"在常量池中创建了ab对象,存放在常量池的#2位置里,这个时候new


String就只在堆中创建了一个String对象,常量池中因为已经有了,就不会再创建了。


这样的情况下,只创建了一个对象。


(六)总结


虽说怎么写代码都能实现一定的功能,但是有时候换种写法可以省下很多资源。比如将:


Stringstr=newString("abc")

写成:

Stringstr="abc"

虽然只是小小的改动,但是在频繁调用的方法中,就有可能避免创建了百万个String实例。


对于有一定开发经验的程序员,建议可以读一下《Effect-Java》,里面有许多写代码的更优方式。


我是鱼仔,我们下期再见!

相关文章
|
4月前
|
安全 Java API
【Java字符串操作秘籍】StringBuffer与StringBuilder的终极对决!
【8月更文挑战第25天】在Java中处理字符串时,经常需要修改字符串,但由于`String`对象的不可变性,频繁修改会导致内存浪费和性能下降。为此,Java提供了`StringBuffer`和`StringBuilder`两个类来操作可变字符串序列。`StringBuffer`是线程安全的,适用于多线程环境,但性能略低;`StringBuilder`非线程安全,但在单线程环境中性能更优。两者基本用法相似,通过`append`等方法构建和修改字符串。
74 1
|
1月前
|
索引 Python
String(字符串)
String(字符串)。
29 3
|
2月前
|
NoSQL Redis
Redis 字符串(String)
10月更文挑战第16天
49 4
|
2月前
|
canal 安全 索引
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
41 5
|
2月前
|
存储 JavaScript 前端开发
JavaScript 字符串(String) 对象
JavaScript 字符串(String) 对象
48 3
|
4月前
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
3月前
|
存储 C++
C++(五)String 字符串类
本文档详细介绍了C++中的`string`类,包括定义、初始化、字符串比较及数值与字符串之间的转换方法。`string`类简化了字符串处理,提供了丰富的功能如字符串查找、比较、拼接和替换等。文档通过示例代码展示了如何使用这些功能,并介绍了如何将数值转换为字符串以及反之亦然的方法。此外,还展示了如何使用`string`数组存储和遍历多个字符串。
|
4月前
|
C# 开发者 UED
WPF开发者必备秘籍:深度解析文件对话框使用技巧,打开与保存文件原来如此简单!
【8月更文挑战第31天】在WPF应用开发中,文件操作是常见需求。本文详细介绍了如何利用`Microsoft.Win32`命名空间下的`OpenFileDialog`和`SaveFileDialog`类来正确实现文件打开与保存功能。通过示例代码展示了如何设置文件过滤器、初始目录等属性,并使用对话框进行文件读写操作。正确使用文件对话框能显著提升用户体验,使应用更友好易用。
106 0
|
4月前
|
API C# 开发者
WPF图形绘制大师指南:GDI+与Direct2D完美融合,带你玩转高性能图形处理秘籍!
【8月更文挑战第31天】GDI+与Direct2D的结合为WPF图形绘制提供了强大的工具集。通过合理地使用这两种技术,开发者可以创造出性能优异且视觉效果丰富的WPF应用程序。在实际应用中,开发者应根据项目需求和技术背景,权衡利弊,选择最合适的技术方案。
204 0
|
4月前
|
存储 JSON NoSQL
揭秘Redis字符串String的隐藏技能!从基础到进阶,让你的数据存储操作秒变高大上!
【8月更文挑战第24天】Redis中的字符串类型作为其基石,不仅能够存储从简单文本到复杂格式如JSON的各种数据,还能通过多样化的命令实现包括但不限于自增自减、设置过期时间等高级功能,极大提升了其实用性和灵活性。例如,使用`SET`命令可添加或更新键值对,`GET`获取值,`DEL`删除键;同时,`INCR`和`DECR`支持对整数值的原子性增减操作,非常适合实现计数器等功能;通过`EXPIRE`命令设置过期时间,则适用于需要限时存储的应用场景。尽管名为“字符串”,但实际上还可存储图片、音频文件的Base64编码等形式的数据,为开发者提供了强大而灵活的工具。
60 0