Java的数据类型-之String

300 阅读2分钟

Java的数据类型

思维导图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tiqGcpjR-1607873381978)(en-resource://database/3023:0)]

Java数据类型在内存中的存储:

  1. 基本数据类型的存储原理
    1. 不存在“引用”
    2. 直接存储在内存中的内存栈上的,数据本身的值就是存储在栈空间里;
  2. 引用类型:
    1. 继承于Object类(也是引用类型)
    2. 使用Java内存堆和内存栈来进行这种类型的数据存储,“引用”是存储在有序的内存栈上的,而对象本身的值存储在内存堆上

谈及String

  1. 首先String是一个类,所以属于引用数据类型。
String helloString = new String("helloString");
String s3 = new String("Runoob").intern(); // “有的话就直接返回其引用”,指的是会把字面量对象的引用直接返回给定义的对象。过程中是不会在Java堆中再创建一个String对象的。

上面这个代码定义了几个个对象。 若常量池中已经存在"helloString",则直接引用,只会创建一个对象,如果常量池中不存在,则先创建后引用,就是两个对象;但是为了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串常量池。在JVM运行时区域的方法区中,有一块区域是运行时常量池,主要用来存储编译期生成的各种字面量和符号引用。


graph TD
A[模块A] -->|1| B(进行编译)
B --> C{字符串是否在常量池}
C -->|是| D[字符串是否在常量池]
C -->|否| E[符号引用和字面常量加入Class文件常量池]

在运行期, new String("helloString");在Java堆中创建一个字符串对象的,而这个对象所对应的字符串字面量是保存在字符串常量池中的。对象的符号引用helloString是保存在Java虚拟机栈上的,

String s1 = "Runoob"; // String 直接创建 
tring s2 = "Runoob"; // String 直接创建 
String s3 = s1; // 相同引用 
String s4 = new String("Runoob");// String 对象创建
String s5 = new String("Runoob"); // String 对象创建

System.out.println(s1 == s2);  // true
System.out.println(s4 == s5); // false
System.out.println(s4.euqals(s5)); // true

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-htVHnMM5-1607873381990)(en-resource://database/3025:0)]

所以比较的就是字面量的内容,就必须使用euqals;

  1. intern方法
String s1 = "Runoob"; // String 直接创建 
String s2 = new String("Runoob").;
String s3 = new String("Runoob").intern();

上面的代码都是定义一个字符串对象,然后将其字符串字面量保存在常量池中,并把这个字面量的引用返回给定义好的对象引用。如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z61Gr8K1-1607873381994)(en-resource://database/3029:0)]

在不调intern情况,s3指向的是JVM在堆中创建的S3对象的引用的。但是当执行了intern方法时,s3将指向字符串常量池中的那个字符串常量。由于s1和s3都是字符串常量池中的字面量的引用,所以s1==s3。但是,s2的引用是堆中的对象,所以s2!=s1。