> 技术文档 > [1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作

[1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作


Java基础学习大纲


一、String实例化方式:

1.1.构造器介绍:

[1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作


1.2.创建String对象:

a.方式一:通过字面量定义的方式

[1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作

b.方式二:通过new + 构造器的方式

[1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作
[1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作


二、字符串对象的存储分析:

2.1.字面量方式:

  • 1.通过字面量方式:S1和S2的数据存储在方法区中的字符串常量池中
    [1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作

2.2.new方式:

  • 1.通过new方式的话,s3和S4保存的是地址值,是数据 在堆空间中开辟空间之后对应的地址值
    [1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作

2.3.案例内存分析:

  • 1.案例1(详细的内存解析图):
    [1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作
  • 2.案例2:
    [1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作

2.4.代码测试:

测试1:

 @Test public void test2(){ //通过字面量定义的方式:此时的s1和s2的数据javaEE声明在方法区中的字符串常量池中 String s1 = \"javaEE\"; String s2 = \"javaEE\"; //通过new+构造器的方式:此时的s3和s4保存的地址,是数据在堆空间中开辟空间以后对应的地址 String s3 = new String(\"javaEE\"); String s4 = new String (\"javaEE\"); System.out.println(s1==s2);//true System.out.println(s1==s3);//false System.out.println(s1==s4);//false System.out.println(s3==s4);//false }

[1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作


测试2:

[1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作


三、字符串的拼接操作:

3.1.先说结论:

  • 1.常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量
  • 2.只要其中有一个是变量,结构就在堆中
  • 3.如果拼接的结果调用intern()方法,返回值就在常量池中

3.2.代码测试

 @Test public void test3(){ String s1 = \"javaEE\"; String s2 = \"hadoop\"; String s3 = \"javaEEhadoop\"; String s4 = \"javaEE\"+\"hadoop\"; String s5 = s1 + \"hadoop\";//先new,然后在堆中再指向常量,s5是指向的地址值 String s6 = \"javaEE\"+s2; String s7 = s1 +s2; System.out.println(s3 == s4);//true System.out.println(s3 == s5);//false System.out.println(s3 == s6);//false System.out.println(s3 == s7);//false System.out.println(s5 == s6);//false System.out.println(s5 == s7);//false System.out.println(s6 == s7);//false String s8 = s5.intern();//返回值得到的s8使用的是常量池中已存在的\"javaEEhadoop\" System.out.println(s3 == s8);//true }}

3.3.画图分析:

  • s4 = s1 + 常量:底层实际上进行+的时候(这个+两边至少有1个变量),会创建一个StringBuilder对象,,进行字符串的拼接,最后的时候会自动调用StringBuilder对象的toString()方法,再将StringBuilder转变为String对象
    [1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作

3.4.面试题:

a.面试题1:

  • 1.String s = new String(\"asd\")方式创建对象,在内存中创建了几个对象
    • 创建了几个2个对象: 一个是在堆空间中new结构, 另一个是char[]对应的常量池中的数据:“abc”
  • 2.请说明两种创建方式的区别:
    [1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作

b.面试题2:

public class StringTest {String str = new String(\"good\");char[] ch = { \'t\', \'e\', \'s\', \'t\' };// str是代表的地址值public void change(String str, char ch[]) {str = \"test ok\";ch[0] = \'b\';}public static void main(String[] args) {StringTest ex = new StringTest();ex.change(ex.str, ex.ch);System.out.println(ex.str);//goodSystem.out.println(ex.ch); //best}}

c.面试题3:

[1-01-01]第42节:不可变字符序列 - String类的实例化与拼接操作