1. String创建
Java String的不可变的(immutable),查看源码可以知道,String使用private final char[] value来实现字符串存储的。
String的创建方式有两种,如下:
(1) String str = "aaa";
(2) String str = new String("aaa");
这两种的区别是:
(1)是在编译期,由于两个常量相加,编译器会进行优化,在编译的时候就处理成“ab”了;
(2)是在运行期,这里的"aaa"本身就是contant pool中的一个对象,而在运行时执行new String()时,将pool中的对象复制一份放到heap中,并且把heap中的这个对象的引用交给str持有。这条语句就创建了两个对象。这是个Java面试经常出现的问题,但是莫枢大牛(http://rednaxelafx.iteye.com)写了一篇《请别再拿“String s = new String("xyz");创建了多少个String实例”来面试了吧》,深入学习了一下,其实没那么简单
还有一种是java可以直接使用+对两个字符串进行连接:
String str1 = "a";
String str2 = "b"
String str3 = str1+str2;
因为Java对String类型重载了加号(+)操作符,这种在代码编译的时候,会处理成StringBuilder(JDK 5及以上)
或StringBuffer(JDK 5 以下)进行连接。如会变成
String str3 = (new StringBuilder("a")).append(str2).toString();
详细的源码可以查看%JAVA_HOME%/lib/tools.jar中,com.sun.tools.javac这个包下面的代码。
扩展1:常量池(Constant Pool)
在java编译好的class文件中,有个区域称为Constant Pool,它是一个由数组组成的表,用来存储程序中使用的各种常量,包括Class、String、Integer等各种基本的Java数据类型
对于值相同的String常量,在Constant Pool中只会创建一个,所以在编译好的class文件中,我们只能找到一个string常量。
在程序执行时,Constant Pool会存储在Method Area中,而不是堆中。详细的java内存区域划分见博文Java内存区域学习笔记
2. String intern方法
官方API的解释,返回字符串对象的规范化表示形式。即返回一个字符串,内容与此字符串相同,但它保证来自字符串池中。
尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列的动作和操作。在调用"ab".intern()方法的时候会返回"ab",但是这个方法会首先检查字符串池中是否
有"ab"这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然后返回这个字符串的引用。
3. StringBuffer的创建
本身String是不可变的,但是却可以如
String a = "a";
a = a+"b";
StringBuffer扮演了String的可变配套类角色。
StringBuffer sb = new StringBuffer("abc")
sb = sb.append("22");
这两个代码产生了两个对象,“abc”本身与经过new创建出来sb,StringBuffer的特点是改变对象本身而不是创建新的对象,因此,此处的sb.append(“22”)都是对同一个对象进行处理。
这个也是StringBuffer比new String()性能好的原因,因为StringBuffer对字符串的改变不会生成新的对象。
4. StringBuffer与StringBuilder的异同
其异同为:一、长度都是可扩充的;二、StringBuffer是线程安全的,StringBuilder是线程不安全的。
StringBuilder一个可变的字符序列是5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。
该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。
如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。如果去掉线程安全,那两者就基本一样的。查看源码可以知道
StringBuffer所有方法(构造方法除外,因为没有必要)签名中都使用 synchronized 限定。
分享到:
相关推荐
字符串是Java中非常特殊的对象类型,字符串的创建和拼接有很多细节,比如字符串连接使用'+'时,会生成多个String对象,而使用StringBuilder或者StringBuffer则更为高效。另外字符串池的存在也使得字符串的操作更加...
**1.6 JAVA面试题解惑系列(六)——字符串(String)杂谈** - **知识点**:深入探讨字符串处理技术,包括字符串拼接、比较、格式化等常见操作的内部实现,以及性能优化建议。 **1.7 JAVA面试题解惑系列(七)——...
Java中的字符串(String)是编程面试中的热门话题,其特性与操作是面试官常常用来考察候选人基础知识的手段。本文将深入探讨String对象的一些关键知识点。 首先,我们要了解`String`类的`length()`方法。这个方法返回...
### Java字符谜题 Java中字符以Unicode编码,因此处理字符时需要理解Unicode的特性。例如,`'\u0061'`表示字符'a',而单引号内的字符不是字符串,而是字符常量。此外,字符和字符串的操作有特定的方法,如`charAt()...
1. **字符串常量池**:Java中有一个特殊的内存区域用来存储字符串字面量,这个区域称为字符串常量池。字符串常量池中存储的字符串不会重复。 2. **字符串的创建方式**:可以通过直接赋值或使用new关键字创建。 **...
这本书可能涵盖了一些容易误解的概念,如字符串的不可变性、equals()与hashCode()的关系,以及异常处理的最佳实践。 通过阅读这些资料,开发者不仅可以强化自身的Java基础知识,还能提升解决问题的能力,为面试做好...
5. **字符串操作**:String类在Java中非常常用,其不可变性可能困扰初学者。文档可能会涵盖字符串的创建、连接、查找、替换等操作。 6. **IO流**:输入/输出流是处理数据输入和输出的关键,包括文件读写和网络通信...
### JAVA面试题解惑系列知识点总结 #### 一、类的初始化顺序 **知识点概述:** 在Java中,类的初始化顺序是一个常见的面试问题。它主要涉及到类成员(包括静态和非静态)的加载和初始化过程。理解这些基础知识有助...
3. **字符串操作**:Java中的字符串是不可变的,这意味着任何对字符串的操作都会创建新的对象。理解这一点对于优化代码和避免内存浪费至关重要。 4. **数组与集合**:Java提供了多种数据结构,如数组、ArrayList和...
JAVA中的String对象是不可变的,创建String对象时,会考虑字符串常量池,如果字符串值已经存在,将返回池中的引用,否则会在堆中创建新对象。这涉及到String对象的intern()方法和字符串拼接的性能问题。 3. final...
当我们创建一个 String 对象时,JAVA 虚拟机(JVM)首先会在字符串池中查找是否已经存在了该对象,如果存在,则不再创建新的对象,直接返回已存在对象的引用;如果不存在,则创建新的对象,并将其加入字符串池中。 ...
但如果两个操作数都是非字符串类型,如字符`'H'`和`'a'`,Java会尝试将它们转换为字符串后再进行连接。这里可以使用多种方法实现连接,包括预置空字符串、使用`String.valueOf()`方法、字符串缓冲区或JDK 5.0及更高...
面试中常见的问题是关于字符串连接或复制操作时,实际创建了多少个对象。例如,"abc" + "def" 实际上会产生几个String对象?答案是可能会有两个,一个是临时的StringBuilder对象,另一个是最后的连接结果。 3. **...
在处理包含转义字符的字符串时,必须明确了解每个转义字符的具体功能及其在Java中的使用规则。 **谜题15:令人晕头转向的Hello** - **描述**:涉及到字符串的输出,结果与预期不符。 - **解惑**:字符串输出时,...
文档提到了Java中浮点数转换为字符串时的特殊规则。当使用`Double.toString`方法将`double`类型的值转换为字符串时,结果是足以将`double`值与最靠近的临近值区分开来的最短小数。因此,当你期望看到`0.90`时,实际...