`
willsunforjava
  • 浏览: 167891 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java 字符串解惑

 
阅读更多

 

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面试题解惑系列合集

    字符串是Java中非常特殊的对象类型,字符串的创建和拼接有很多细节,比如字符串连接使用'+'时,会生成多个String对象,而使用StringBuilder或者StringBuffer则更为高效。另外字符串池的存在也使得字符串的操作更加...

    JAVA面试题解惑系列(六)——字符串(String)杂谈[收集].pdf

    Java中的字符串(String)是编程面试中的热门话题,其特性与操作是面试官常常用来考察候选人基础知识的手段。本文将深入探讨String对象的一些关键知识点。 首先,我们要了解`String`类的`length()`方法。这个方法返回...

    java解惑 java 表达式谜题 java 字符谜题 java 循环谜题 java 异常谜题

    ### Java字符谜题 Java中字符以Unicode编码,因此处理字符时需要理解Unicode的特性。例如,`'\u0061'`表示字符'a',而单引号内的字符不是字符串,而是字符常量。此外,字符和字符串的操作有特定的方法,如`charAt()...

    Java面试解惑宝典(高清PDF版)

    这本书可能涵盖了一些容易误解的概念,如字符串的不可变性、equals()与hashCode()的关系,以及异常处理的最佳实践。 通过阅读这些资料,开发者不仅可以强化自身的Java基础知识,还能提升解决问题的能力,为面试做好...

    Java_解惑(PDF)

    5. **字符串操作**:String类在Java中非常常用,其不可变性可能困扰初学者。文档可能会涵盖字符串的创建、连接、查找、替换等操作。 6. **IO流**:输入/输出流是处理数据输入和输出的关键,包括文件读写和网络通信...

    JAVA面试题解惑系列合集.docx

    ### JAVA面试题解惑系列知识点总结 #### 一、类的初始化顺序 **知识点概述:** 在Java中,类的初始化顺序是一个常见的面试问题。它主要涉及到类成员(包括静态和非静态)的加载和初始化过程。理解这些基础知识有助...

    java解惑(源代码+教程)

    3. **字符串操作**:Java中的字符串是不可变的,这意味着任何对字符串的操作都会创建新的对象。理解这一点对于优化代码和避免内存浪费至关重要。 4. **数组与集合**:Java提供了多种数据结构,如数组、ArrayList和...

    JAVA面试题解惑系列(二)——到底创建了几个String对象-JAVA程序员JAVA工程师面试必看.pdf,这是一份不错的文件

    当我们创建一个 String 对象时,JAVA 虚拟机(JVM)首先会在字符串池中查找是否已经存在了该对象,如果存在,则不再创建新的对象,直接返回已存在对象的引用;如果不存在,则创建新的对象,并将其加入字符串池中。 ...

    讲解Java解惑的PPT2

    但如果两个操作数都是非字符串类型,如字符`'H'`和`'a'`,Java会尝试将它们转换为字符串后再进行连接。这里可以使用多种方法实现连接,包括预置空字符串、使用`String.valueOf()`方法、字符串缓冲区或JDK 5.0及更高...

    JAVA面试题解惑系列

    面试中常见的问题是关于字符串连接或复制操作时,实际创建了多少个对象。例如,"abc" + "def" 实际上会产生几个String对象?答案是可能会有两个,一个是临时的StringBuilder对象,另一个是最后的连接结果。 3. **...

    java 解惑.pdf

    在处理包含转义字符的字符串时,必须明确了解每个转义字符的具体功能及其在Java中的使用规则。 **谜题15:令人晕头转向的Hello** - **描述**:涉及到字符串的输出,结果与预期不符。 - **解惑**:字符串输出时,...

    iava解惑,深入剖析java

    可能考察字符串排序,Java提供了`Arrays.sort()`方法用于排序字符数组或字符串数组。 谜题13:畜牧场 这个谜题可能与数组或集合的计数有关,需要统计特定元素的数量。 谜题14:转义字符的溃败 可能涉及字符串中的...

Global site tag (gtag.js) - Google Analytics