对于JAVA的String在很长一段时间里都没有系统地去整理下,现在写个笔记,加深印象。
String在JAVA中不属于8个基本数据类型,这个在笔试面试的时候要小心,String是JAVA中的一个类,他有自己的构造器,可以new,比较特殊的地方在于String是常量,一旦被创建出来就无法改变。
举例说明
String str = "a";
str = "ab";
str = "a";
上面三句话实际上是产生了2个字符串对象,根据String的不可变特性,当str由a变为ab的时候,实际上并不是直接在str的内存地址上直接进行值修改,而是给了str另外一个值为ab的字符串对象的内存地址,因此a这个字符串还是存在的。
另外一个要知道的知识点是字符串对象的存储区域,要知道在JVM中字符串对象被创建出来后就会被放置在一个称为字符串池的内存区域,这个区域在JAVA的内存模型中属于静态内存区,还是以上面的代码为例说明,第一句话,实际上是JVM在字符串池中创建了一个值为a的字符串对象并将该对象的内存地址赋给了str的内存区域,这样的操作就称为引用;第二句话,JVM还是在字符串池中创建了一个值为ab的字符串对象,并赋给str的内存新的一个地址,也就是ab字符串对象的地址;第三句话,由于值为a的对象已经在池中存在了,因此JVM不会再创建新的对象,而是将之前就有的对象的地址赋给了str,JVM以此来提高字符串这种常用对象的复用性。
一开始的时候就讲到String也是有构造器的,也是可以new的,但是使用下面的代码
String str = new String("abc");
与直接赋字符串常量,实际的工作流程就不太一样了,JVM会在堆中开辟一块内存区域,然后将堆的地址赋给str的内存区域。因此就有了下面的经典考题
String str1 = "abc";
String str2 = new String("abc");
String str3 = new String("abc");
System.out.println(str1 == str2);//false
System.out.println(str1 == str3);//false
System.out.println(str2 == str3);//false
上面三句代码一共产生了几个String对象,答案应该是3个,在字符串池中1个,在堆中2个,并且所有的打印也应该都输出false,原因是他们的内存地址都不一样。
然后还有一个疑问的是那么对于字符串的+操作,到底产生了多少String对象呢,这里要考虑下面两种情况。
第一种情况是字符串常量连接,代码如下:
String str1 = "ab" + "cd";
String str2 = "abcd";
System.out.prinltn(str1 == str2);//true
你发现在整个字符串连接的表达式中出现的都是字符串常量,那么这种情况,在编译期他们就直接被合并为abcd这个字符串常量了,而不需要产生中间的ab和cd,因此只产生了一个字符串对象。所以打印的结果是true,str1和str2都是池中对象的引用。
第二种情况是字符串变量连接,代码如下:
String str1 = "ab";
String str2 = "cd";
String str3= str1 + str2;//new String("ab")+new String("cd")
String str4 = "abcd";
System.out.println(str3 == str4); // false
你发现在字符串连接的表达式中出现了字符串变量(只要是编译器不能直接确定值的都是变量,所以使用构造器生成的String也视为变量),这种情况,JVM会在堆中创建一个StringBuffer类,并使用ab的值作为这个StringBuffer类的初始化,然后调用StringBuffer的append方法,进行字符串追加,追加完毕后,在调用StringBuffer的toString方法在堆中创建一个String对象,并将该String对象的地址赋给str3的内存区域。所以上面的代码str1,str2,str4在池中创建了3个String对象,str3由于toString方法在堆中创建了一个String对象,由于+操作符在堆中创建了一个StringBuffer对象。所以最后的打印结果也就容易理解了,str3的值是堆中的String的地址,而str4是池中的String的地址,然后不一样。
最后是String中有个方法比较特殊,叫intern方法,当调用 intern 方法时,如果池已经包含一个等于此 String
对象的字符串(用 equals(Object)
方法确定),则返回池中的字符串。否则,将此 String
对象添加到池中(这里的添加是指在池中创建一个值相同的String对象,而原来的String对象还是被保留着的),并返回此 String
对象的引用。 所以看下下面代码理解下这个方法的意思。
String str1 = new String("abc");
System.out.println(str1 == str1.intern());//false
String str2 = "abc";
System.out.println(str2 == str1.intern());//true
另外补充一点是所有的字符串操作方法,如substring,concat等,都会在堆中产生一个新的String对象。所以现在对于常见的问一段代码中产生了多少字符串对象的问题应该都能够应对自如了。
然后,我们就可以开始介绍StringBuffer,由于String的不可变性,如果要对String进行追加或者裁减的操作会产生很多额外的String对象,所以我们推荐当需要进行大量的字符串操作的时候,使用StringBuffer来完成,因为StringBuffer是可变的。
StringBuffer sb="ab";
s.append("cd");
如上面实际上就只产生一个StringBuffer对象。
贴一个百度百科对StringBuffer的介绍,还是比较全面的 http://baike.baidu.com/view/1486261.htm
StringBuffer和StringBuilder可以算是双胞胎了,这两者的方法没有很大区别。但在线程安全性方面,StringBuffer允许多线程进行字符操作。这是因为在源代码中StringBuffer的很多方法都被关键字synchronized 修饰了,而StringBuilder没有。
做个总结就是:单线程就用StringBuilder吧,多线程就用StringBuffer,要是你只是存取下数据String就可以了。
分享到:
相关推荐
此外,了解如何使用StringBuilder或StringBuffer进行字符串拼接以提高性能也非常重要。 最后,我们将目光转向Java的IO流。Java的IO流分为字符流和字节流,分别处理字符和字节数据。它们有输入流(InputStream/...
### Android知识点整理 #### Java基础 1. **面向对象的理解** - 面向对象编程(OOP)是一种编程范式,它使用“对象”来设计软件。对象包括数据(即字段,也称为属性)和操作这些数据的方法。 - 封装:将对象的...
这份"Java核心知识点整理.rar"压缩包包含了对Java语言全面而深入的总结,对于初学者和有一定经验的开发者来说,都是宝贵的参考资料。下面,我们将详细探讨Java的核心知识点,并按照一个合理的学习路线进行阐述。 1....
- StringBuilder与StringBuffer:线程安全的字符串操作。 5. **集合框架** - List:ArrayList、LinkedList,线性存储,增删查改操作。 - Set:HashSet、TreeSet,不允许重复元素。 - Map:HashMap、TreeMap、...
根据提供的文件信息,我们可以整理出以下相关知识点: ### 1. 构造函数与重写、重载 构造函数(Constructor)在面向对象编程中扮演着重要的角色,它主要用于初始化对象的状态。对于构造函数是否可以被重写或重载的...
综上所述,“Java面试葵花宝典”涵盖了Java面试中的基础知识点,包括但不限于 `String` 类型的理解、`Integer` 类的使用、各种Wrapper类的功能及其方法,以及 `StringBuilder` 和 `StringBuffer` 的区别和使用场景。...
Java知识点详解: 1. String、StringBuffer、StringBuilder的对比: - String是不可变的,每次操作都会创建新的对象,不推荐在频繁修改字符串的情况下使用。 - StringBuffer和StringBuilder都是可变的,它们在原...
Java中有三种主要的字符串操作类:String、StringBuffer和StringBuilder。 - String是不可变的,每次修改都会创建新对象,不适合频繁修改字符串内容。 - StringBuffer和StringBuilder在可变性上相同,可以在原...
Java中的字符串是不可变的,理解String、StringBuilder和StringBuffer的区别,以及如何高效地操作字符串是非常重要的。 8. **MyBatis** MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。...
**知识点7:String与StringBuffer的区别** - **不可变性**:`String`对象是不可变的,而`StringBuffer`对象是可以修改的。 - **线程安全性**:`StringBuffer`提供了线程安全的方法,适用于多线程环境;`String`则不...
1. String、StringBuffer、StringBuilder: - String 是不可变对象,适合在常量池中使用,多次拼接时效率较低。 - StringBuffer 和 StringBuilder 在字符串可变场景中使用,StringBuilder 更高效但非线程安全,...
这份名为《整理的Java-EE面试总结.pdf》的文档是一份关于Java基础面试知识点的总结,内容涉及了多个在面试中常见的问题和概念,以及它们的区别和使用场景。根据提供的文件信息,下面将详细解读其中的关键知识点。 ...
书中还比较了String、StringBuilder和StringBuffer的区别,并探讨了在什么情况下使用“+”运算符连接字符串比使用StringBuilder或StringBuffer更高效。 Java的数据类型部分详细列出了Java的基本数据类型(byte、...
本资源摘要信息中整理了 Java 面试中常见的知识点,涵盖了 Java、Web、数据库(MYSQL、ORACLE)、SSH、SSM 等方面的大部分知识,包括面试官常问的问题。 一、面向对象的特征 面向对象的特征包括封装、继承和多态。...
- **String、StringBuffer、StringBuilder**:在Java中,String是不可变的,每次修改都会创建新对象;StringBuilder和StringBuffer是可变的,适合在多线程环境中进行字符串拼接,后者提供线程安全。 除了这些基础...
- **知识点**: `String`表示不可变字符串,而`StringBuffer`表示可变字符串。 - **解释**: 当字符串经常需要修改时,使用`StringBuffer`更为合适。`StringBuilder`与`StringBuffer`类似,但前者不保证线程安全。 ##...
根据提供的文件信息,我们可以整理出以下关于 Java 的基础知识点: ### 1. 基本概念 #### 1.1 对象与类 - **对象(Object)**:是类的一个实例,拥有类定义的属性和行为。 - **类(Class)**:是一组具有相同属性...
本文将深入探讨Java字符串的赋值及其相关知识点,帮助你为面试做好充分准备。 1. **字符串常量池** Java中的字符串对象在内存中有两种存在方式:栈和堆。当使用字面量创建字符串时,如`String str = "abc"`,字符...
### Java基本数据类型与String类型 #### Java的基本数据类型 Java提供了八种基本的数据类型...以上是根据给定文件标题、描述及部分内容所总结的相关知识点,希望能帮助你更好地理解 Java 编程语言的核心概念及其应用。
另外,面试中还提到了`String`, `StringBuffer`和`StringBuilder`的区别。这三者都是用来处理字符串的类,但有以下几点不同: - `String`是不可变对象,一旦创建就不能修改。这意味着每次对`String`对象的操作(如...