String类的疑惑

Java String类的疑惑:

  • 创建
  • 拼接

String是java的常用类之一,本质是字符数组char[]。String类是final类,不可被继承。关于String的创建,可以通过new来创建对象,也可以直接赋值。但是这两种创建方式的实现机制是不同的。提到对象的创建,我们就会想到堆、栈,这里还有一个string pool的概念,JVM维护一个String池,池中的string对象不可重复,string池不属于堆栈,而是一个常量池。

一、创建

创建一个String对象,主要有两种方式:

String str1 = new String("abc"); //在string池中创建abc对象,在堆中创建abc对象,栈中的str1指向该对象
String str2 = "abc";//在string池中查找abc对象,已存在,直接将栈中的str2指向该对象

仔细看两行注释,执行完第一行代码后,内存如图:

执行完第二行代码,内存如图:

可通过内存比较来验证:

先自己思考一下结果再往下继续啦!

String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
System.out.println(str1 == str2);
System.out.println(str1 ==str3);
System.out.println(str1 == "abc");
System.out.println(str3 =="abc");
System.out.println(str1 == str3.intern());
System.out.println(str3 == str3.intern());

运行结果:

解析:

==比较的是内存地址,

str1==str2;// 都指向string池中的对象,所以返回true

str1==str3;//str1指向string池中的对象,str3指向堆中对象,所以,返回false

str1==“abc”; //都指向string池中的对象,所以返回true

str3==”abc“;//str3指向堆内存对象,另一个是string池中的对象,所以,返回false

str1==str3.intern(); //都指向string池中的对象,返回true

str3==str3.intern();//str3指向堆内存对象,str3.intern()指向string池中的对象,所以,返回false

intern()方法是返回字符串对象的规范化表示形式,也就是说当调用intern()时,如果string池中已经包含一个等于(equals)此string对象的字符串,则返回池中的字符串。

二、拼接

先来思考一下执行结果:

<span style="white-space:pre">	</span>String hello = "hello";
	String hel = "hel";
	String lo = "lo";
	System.out.println(hello == "hel"+"lo");
	System.out.println(hello == "hel"+"looo");
	System.out.println(hello== "hel" + lo);

运行结果:

解析:

  • 如果+连接的都是常量时,先判断string池中有没有hello,如果存在,直接返回其地址,不再重新创建。
  • 如果+连接的有对象类型时,则直接在堆中生成一个新对象。

关于String拼接的继续思考:

由于String类是final的,也就是对象一旦创建,就不能改变其内在状态了,但是,拼接操作是要改变String的内部状态的,在这种矛盾下,要维护string的非可变性,只好在拼接完成后再创建一个新的String对象,也就是说,每执行一次拼接操作,都会产生新对象的产生。当大量指向拼接操作时,就会导致大量对象的创建,这样,就产生了性能问题。

为了解决这个问题,jkd为string类提供了一个可变的配套类StringBuffer。由于StringBuffer是可变的,拼接时仅仅是改变了内部数据结构,而不会创建新对象,因此,性能上有很大的提高。

String类的疑惑

时间: 2024-10-13 07:02:19

String类的疑惑的相关文章

String类replaceAll方法正则替换深入分析

作者网址: https://my.oschina.net/shipley/blog/98973 背景:      前几天有人发了一个关于下面问题的贴,对这个有点好奇,故花时间做了点研究.        对单个反斜杠字符串替换成双斜杠的Java实现如下:    String s = "\\";    方法一:String sr1 = s.replaceAll("\\\\", "\\\\\\\\");    方法二:String sr1 = s.re

String类,StringBuffer类转字符数组

String不可变类型和StringBuffer可变类型 String类和StringBuffer类都是字符串表示类,区别在于String对象引用变量是不可变的,而StringBuffer类对象引用变量是可变的. 我当时学的时候也会很不理解这个可变不可变的区别,后面看了一篇博客才懂了这个意思(https://www.cnblogs.com/yumiaoxia/p/9010721.html#commentform). 方法传参,基本数据类型传的是常量值,而引用数据类型传的是地址值.但是String

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中

String类实现

String类是应用框架中不可或缺的类 重载运算符实现字符串的操作 #idndef IOTECK_STRING_H_#define IOTECK_STRING_H_namespace iotek{ class String { public: String(const char*=NULL); ~String(); String(const String&); //拷贝构造函数 //String a; a=b; String& operator=(const String &);

String类

一.概述 Sting s1 = "abc";    //s1是一个类类型变量,"abc"是一个对象. String s2 = new String("abc"); //s1 . s2 的区别: 前者在内存中有一个对象,后者在内存中有两个对象. s1.equals(s2) 为true  因为 String复写了equals方法 二.常见的功能-获取和判断 获取: 1.int length(); 获取长度 2.char chatAt(int inde

C++实现String类

这是一道十分经典的面试题,可以短时间内考查学生对C++的掌握是否全面,答案要包括C++类的多数知识,保证编写的String类可以完成赋值.拷贝.定义变量等功能. #include<iostream> using namespace std; class String { public: String(const char *str=NULL); String(const String &other); ~String(void); String &operator =(cons

java中String类的构造函数

String类中的构造函数String(); 构造一个空字符串对象String(byte[] bytes); 通过byte数组构造字符串对象String(byte[] bytes,int offset,int length);通过byte数组,从offset开始,总共length长的字节构造字符串对象String(char[] value); 通过char数组构造字符串对象String(byte[] char,int offset,int length);通过char数组,从offset开始,总

Java (六、String类和StringBuffer)

Java String 类 字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 创建字符串 // ==比较的是字符串在栈中存放的首地址,而equals()比较的是两个字符串的内容是否相同 //普通的声明字符串的方法,只会在字符串常量池里开辟空间,并且开辟空间之前,会检查字符串常量池里是否已存在 //相同的数据,如果有,直接指向已存在的数据,如果没有会在字符串常量池里开辟一个新的空间 String s = "ccy"

JAVA API(一)String类和StringBuffer类

1.String类和StringBuffer类 在程序中经常会用到字符串,所谓的字符串就是指一连串的字符,它是由多个单个字符连接而成的.字符串中可以包含任意字符,这些字符必须包含在一对双引号""之内,如"abc".在Java中定义了String和StringBuffer类来封装字符串,并提供了一系列操作字符串的方法,它们都位于java.lang包中,因此不需要导包就可以直接使用.下面将对String类和StringBuffer类详细讲解. 1.1String类的初始