56-Java: String概述、对象创建的内存原理

一、String 概述

  • java.lang.String 类代表字符串,String类定义的变量可以用于指定字符串对象,然后操作该字符串。

  • Java程序中的所有字符串文字(例如:“abc” ; “三国”)都称为此类的对象。

  • 语法格式:

    String name = "关羽";
    String schoolName = "bilibili大学";
    

二、String类的特点详解

1. 不可变字符串类型

  • String其实常常被称为不可变字符串类型,它的对象在创建后不能被更改。

2. 提出问题

在这里插入图片描述
在这里插入图片描述

  • 从上述代码可以看出字符串变量name指向的字符串对象,那为何还说是不可变字符串类型?

3. 解决问题

  • 首先要知道字符串对象存在哪里?

    • 答:以 “” 方式给出的字符串对象,在字符串常量池中存储 ——> 存在堆内存
  • 通过内存题解来解释 字符串类型不可变的原理

  • 图1说明:

    1.第一步: 会将main方法加载到栈内存中运行
    2.第二步: 执行main方法中的第一行程序: String name = "bilibili";
      (2.1) 此时,会将 "bilibili" 加载到堆内存中的字符串常量池,
      然后将字符串常量池的内存地址 赋值给 变量name,此时的name就会指向 "bilibili"。
            解释一下: name中存的其实是字符串常量池的内存地址,只是sum公司做了处理,
            输出到控制台的时候,就是根据这个name存的字符串常量池的内存地址去找到对应的
            字符串进行输出 ——>这里是继承的内容,后面会讲解到,先知道这个意思。
    

    在这里插入图片描述

  • 图2说明:

    3.第三步: 执行main方法中的第二行程序: name += "教育";
      (3.1) 此时,会将 "教育" 加载到堆内存中的字符串常量池,然后把 "bilibili" 和 
      "教育" 进行运算(字符串拼接),运算后,在堆内存中得到一个新对象: "bilibili教育",此时的name就会指向这个新对象: "bilibili教育"。
      		解释一下: 此时我们可以看到字符串常量池中是不会改变的,
      		这就是字符串类型不可变的原因。
    

在这里插入图片描述

  • 图3说明:

    4.第四步: 执行main方法中的第三行程序: name += "中心";
      (4.1) 此时,会将 "中心" 加载到堆内存中的字符串常量池,然后把 "bilibili教育" 和
       "中心" 进行运算(字符串拼接),运算后,在堆内存中得到一个新对象:
        "bilibili教育中心",此时的name就会指向这个新对象: "bilibili教育中心"。
      		解释一下: 此时我们可以看到字符串常量池中的"bilibili"、"教育"、"中心",
      		都不会发生改变,这就是 “String常被称为不可变字符串类型,它的对象在创建后
      		不能被更改” 这句话的原因。
    5.第五步: 执行main方法中的第五行程序: System.out.println(name);
      (5.1) 此时,会根据name指向最新对象:
      	 "bilibili教育中心",在控制台显示: bilibili教育中心。
    

在这里插入图片描述

重点总结

1、String是什么?可以做什么?

  • 字符串类型,可以定义字符串变量 指向 字符串对象

2、String是不可变字符串的原因?

  • String变量每次的修改其实都是产生并指向了新的字符串对象
  • 原来的字符串对象都是没有改变的,所以称不可变字符串

三、创建字符串对象的2种方式

1. 第一种方式

  • 直接使用 “” 定义。(推荐方式)

    String name = "关羽";
    

2. 第二种方式

  • 通过String类的构造器创建对象。

    构造器说明
    public String()创建一个空白字符串对象,不含有任何内容
    public String(String original)根据传入的字符串内容,来创建字符串对象
    public String(char[] chs)根据字符数组的内容,来创建字符串对象
    public String(byte[] chs)根据字节数组的内容,来创建字符串对象

3. 2种方式的示例

package com.app.string;

/**
    目标:String类创建字符串对象的2种方式
 */
public class StringDemo2 {
    public static void main(String[] args) {
        System.out.println("-----------方式一------------");
        // 方式1:直接使用双引号创建字符串对象
        String name = "关羽揍张飞~~";
        System.out.println(name);

        System.out.println("-----------方式二------------");
        // 方式2:
        // 1.public String(): 创建一个空白字符串对象,不含有任何内容(实际开发中几乎不用)
        String s1 = new String();  // s1 = ""
        System.out.println(s1);

        // 2.public String(String): 根据传入的字符串内容,来创建字符串对象(实际开发中几乎不用)
        String s2 = new String("刘备真虚伪~~");
        System.out.println(s2);

        // 3.public String(char[] c): 根据字符数组的内容,来创建字符串对象
        char[] chars = {'B', '站', '教', '育', '中', '心'};
        // 这个构造器 会遍历 字符数组中的每一个字符,然后拼接成一串字符串
        String s3 = new String(chars);
        System.out.println(s3);  // s3 = "B站教育中心"

        // 4.public String(byte[] b): 根据字节数组的内容,来创建字符串对象
        byte[] bytes = {97, 98, 99, 65, 66, 67};
        // 这个构造器 会遍历 字节数组中的每一个字节,然后转换成一个个字符并拼接成一串字符串
        String s4 = new String(bytes);
        System.out.println(s4); // s4 = "abcABC"
    }
}
控制台:

-----------方式一------------
关羽揍张飞~~
-----------方式二------------

刘备真虚伪~~
B站教育中心
abcABC

Process finished with exit code 0

4. 这2种方式有什么区别(面试常考)

  • 以 “” 方式给出的字符串对象,在字符串常量池中存储,而且相同内容只会在其中存储一份。

  • 通过构造器 new 对象,每 new 一次都会产生一个新对象,放在堆内存中。

  • 示例:

    package com.app.string;
    
    /**
        目标:学会String类创建字符串对象的2种方式,以及理解它们的区别
     */
    public class StringDemo2 {
        public static void main(String[] args) {
            System.out.println("String类创建字符串对象的2种方式");
            System.out.println("-----------方式一------------");
            // 方式1:直接使用双引号创建字符串对象
            String name = "关羽揍张飞~~";
            System.out.println(name);
    
            System.out.println("-----------方式二------------");
            // 方式2:
            // 1.public String(): 创建一个空白字符串对象,不含有任何内容(实际开发中几乎不用)
            String s1 = new String();  // s1 = ""
            System.out.println(s1);
    
            // 2.public String(String): 根据传入的字符串内容,来创建字符串对象(实际开发中几乎不用)
            String s2 = new String("刘备真虚伪~~");
            System.out.println(s2);
    
            // 3.public String(char[] c): 根据字符数组的内容,来创建字符串对象
            char[] chars = {'B', '站', '教', '育', '中', '心'};
            // 这个构造器 会遍历 字符数组中的每一个字符,然后拼接成一串字符串
            String s3 = new String(chars);
            System.out.println(s3);  // s3 = "B站教育中心"
    
            // 4.public String(byte[] b): 根据字节数组的内容,来创建字符串对象
            byte[] bytes = {97, 98, 99, 65, 66, 67};
            // 这个构造器 会遍历 字节数组中的每一个字节,然后转换成一个个字符并拼接成一串字符串
            String s4 = new String(bytes);
            System.out.println(s4); // s4 = "abcABC"
    
            System.out.println("——————————————————————————————————\n");
            System.out.println("-------------2种方式的区别----------------");
            System.out.println("方式1: ");
            String str1 = "我是中国人";
            String str2 = "我是中国人";
            System.out.println("str1是否等于str2: " + (str1 == str2));
    
            System.out.println("\n方式2: ");
            char[] chars1 = {'a', 'b', 'c'};
            String str3 = new String(chars1);
            String str4 = new String(chars1);
            System.out.println("str3是否等于str4: " + (str3 == str4));
        }
    }
    
    控制台:
    
    String类创建字符串对象的2种方式
    -----------方式一------------
    关羽揍张飞~~
    -----------方式二------------
    
    刘备真虚伪~~
    B站教育中心
    abcABC
    ——————————————————————————————————
    
    -------------2种方式的区别----------------
    方式1: 
    str1是否等于str2: true
    
    方式2: 
    str3是否等于str4: false
    
    Process finished with exit code 0
    

5. 通过 “” 定义字符串的内存原理

在这里插入图片描述

6. 通过 new 构造器得到字符串对象的内存原理

在这里插入图片描述

重点总结

1、字符串对象的特点有哪些?

  • 字符串不可变
  • 双引号创建的字符串对象,在字符串常量池中存储的是同一个
  • 通过 new 构造器创建的字符串对象,在堆内存中是分开存储的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值