一.创建字符串的几种方式
1、方式一:直接创建
String str1="hello";
2、方式二:使用构造函数
String str2=new string("hello world");
3、方式三:根据字节数组来创建
byte[] array2={97,98,99};
String str3=new String(array2);
4、方式四:根据字符数组来创建
char[] array={'a','b','c'};
String str4=new String(array);
二.不同方式创建的字符串在内存中的情况
1、情况一:由方式一直接创建
String str1="abc";
String str2="abc";
直接将一个常量赋给String 变量的这种情况:字符串常量池中有一个String对象保存了"abc"这个字符串的地址,“abc”这个字符串存储在堆中并且是以节字数组的形式存储的。
具体见下面内存分布图:
System.out.println(str1 == str2);
执行两个字符串比较的代码,有内存分布可知,结果为true(因为地址都是0x666)
补充1: 关于字符串常量池:
如 “abc” 这样的字符串字面值常量, 也是需要一定的内存空间来存储的. 这样的常量具有一个特点, 就是不需要修改(常量嘛). 所以如果代码中有多个地方引用都需要使用 “Hello” 的话, 就直接引用到常量池的这个位置就行了, 而没必要把 “Hello” 在内存中存储两次.
补充2: "=="运算符:
- 对于基本类型:"=="是进行数值的比较
- 对于引用类型:"=="是进行地址值进行比较
- 也就是对于来说:String 使用 == 比较并不是在比较字符串内容, 而是比较两个引用是否是指向同一个对象
2、情况二:由方式二通过new String()来创建
String str3 = new string("hello");
String str4 = new String("Hello");
System.out.println(str3 == str4);
1)首先看一下new String()的具体步骤,见下图
我们要时刻记住“hello”这样的字符串是常量,它一定是存储在字符串常量池中的。
2)有方式二创建字符串内存中的情况,见下图
System.out.println(str3 == str4);
执行两个字符串比较的代码,有内存分布可知,结果为false(因为地址不同)
3、情况三:由方式三通过字节数组来创建
byte[] array5={97,98,99};
String str5=new String(array2);
我们要清楚:像“abc”这样的常量字符串它虽然在字符串常量池中存储,但是它底层还是通过字节数组进行存放的。
具体的内存情况见下图:
4、情况四:由方式四通过字符数组来创建
char[] array6={'a','b','c'};
String str6=new String(array);
由字符数组创建的String()对象的这种情况,分为两步:
- 1>首先需要将字符数组转为字节数组
- 2>再在堆中new一个String对象,保存字节数组的地址
具体内存情况见下图: