解决JAVA中String的所有困惑

储备知识

讲解String之前,需要了解以下Java的内存结构。
Java虚拟机主要管理两种类型的内存:堆和非堆
解决JAVA中String的所有困惑

  • 堆内存
    堆内存是在Java虚拟机启动时创建,是运行时数据区域,所有对象的内存从此处分配(即new出来的对象)。这些内存不需要专门写程序代码进行释放。由专门的垃圾回收来负责。
    优势可以动态的分配内存的大小,垃圾回收机制会自动处理掉不再使用的数据;
    缺点由于在运行时分配内存,所以存取速度较慢。
  • 非堆内存
    非堆内存时堆内存之外的内存。包含方法区、jvm内部处理或优化所需的内存、每个类结构(如运行时常量池、字段和方法数据)以及方法和构造方法的代码。
    (1)栈的优势是,存的是局部变量,存取速度较快,主要存放一些基本类型的变量数据(int float double short long boolean char ),仅次于寄存器,且栈的数据可以共享,缺点是栈中的数据大小与生存期必须是确定的,缺乏灵活性。
    (2)虚拟机会为每个加载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集合,包括直接常量(String、integer、floating point常量)和对其他类型、字段、方法的引用。在程序执行的时候,常量池会存储在方法区,里面的数据可以共享使用,即当常量池中已经有一个数据时再创建相同的数据时,就会直接指向常量池中这个值,不再开辟新的内存空间,提高了效率。

除此之外,还要明白 == 和 equals 的区别。
== 如果是基本数据类型,则比较的是他们值的大小
如果是应用数据类型,== 和 equals 比较的都是内存地址。

1.String类

在Java中,字符串属于对象。

  • 对于String常量,由于String类是final修饰的,它的值一经创建就不可以在再改变,它的值是在常量池中的。

解决JAVA中String的所有困惑

  • 通过new String()创建的对象都存储在堆区。
    解决JAVA中String的所有困惑
  • 常量的值在编译的时候就被确定,在这里“45” 、“6“都是常量,所以s5在编译的时候就可以确定。故s5也位于常量池。因此,s1和s5的地址相同。

解决JAVA中String的所有困惑

  • 结果为false,s2 + s3 计算原理,JVM首先会在堆中创建一个StringBuilder类,然后把计算后s2 +s3 的地址在赋值给s4,

解决JAVA中String的所有困惑

  • 结果为true,s2被final修饰,编译期放入常量池。
    解决JAVA中String的所有困惑