1. String类


1.1 String概述

在API中是这样描述:

String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例
实现。 字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符
串。因为 String 对象是不可变的,所以可以共享。

1.2 创建字符串的2种方式


1.2.1 直接赋值方式

直接赋值方式创建对象是在方法区的常量池

String str="hello";//直接赋值的方式

1.2.2 通过构造方法创建字符

通过构造方法创建字符串对象是在堆内存

String str=new String("hello");//实例化的方式

1.2.3 两种实例化方式的比较

  1. 编写代码比较
public static void main(String[] args) {
        String str1 = "Lance";
        String str2 = new String("Lance");
        String str3 = str2; // 引用传递,str3直接指向str2的堆内存地址
        String str4 = "Lance";
        /* ==:
         * 基本数据类型:比较的是基本数据类型的值是否相同
         * 引用数据类型:比较的是引用数据类型的地址值是否相同
         * 所以在这里的话:String类对象==比较,比较的是地址,而不是内容 */
        System.out.println(str1 == str2);//false
        System.out.println(str1 == str3);//false
        System.out.println(str3 == str2);//true
        System.out.println(str1 == str4);//true
    }

2.内存图分析

java 定义并赋值 java定义字符串并赋值_字符串

可能这里还是不够明显,构造方法实例化方式的内存图:String str = new String(“Hello”);

java 定义并赋值 java定义字符串并赋值_编程语言_02


1.2.4 两种实例化方式的区别

  1. 直接赋值(String str = “hello”):只开辟一块堆内存空间,并且会自动入池,不会产生垃圾。
  2. 构造方法(String str= new String(“hello”);):会开辟两块堆内存空间,其中一块堆内存会变成垃圾被系统回收,而且不能够自动入池,需要通过public String intern();方法进行手工入池。
  3. 在开发的过程中不会采用构造方法进行字符串的实例化。

1.2.5 字符串常量池

在字符串中,如果采用直接赋值的方式(String str=“Lance”)进行对象的实例化,则会将匿名对象“Lance”放入对象池,每当下一次对不同的对象进行直接赋值的时候会直接利用池中原有的匿名对象,我们可以用对象手工入池;

public static void main(String args[]) {
        String str = new String("Lance").intern();//对匿名对象"hello"进行手工入池操作
        String str1 = "Lance";
        System.out.println(str == str1);//true
    }

1.2.5 避免空指向

  • 首先了解: 和public boolean equals()比较字符串的区别在对字符串比较的时候,对比的是内存地址,而equals比较的是字符串内容,在开发的过程中,equals()通过接受参数,可以避免空指向。

1.2.6 String类对象一旦声明则不可以改变;而改变的只是地址,原来的字符串还是存在的,并且产生垃圾

java 定义并赋值 java定义字符串并赋值_jvm_03