详解Java中的inter()方法

新建String对象

我们常用的创建字符串对象的方式有两种

String s1 = "abc";
String s2 = new String("ABC");

解析
s1 是在JVM编译时就能确定的字符串常量,所以会直接加入字符串常量池中,所以此时s1 指向常量池
s2 是通过String的构造方法创建的,并且通过new在堆中开辟了内存,所以s2 指向的是堆中

运行时才能确定的对象,一般都通过new,存放在堆中

字符串常量池

首先要知道字符串常量池这个概念
常量池:管理在编译时被确定并保存在已编译的.class文件中的一些数据,包括关于类、方法、接口中的常量,和字符串常量。
字符串常量池:是Java堆内存中一个特殊的存储区域, 当创建一个String对象时,假如此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。
一般来说,新建一个String对象,都会先去字符串常量池里去找,看存不存在这个字符串,如果存在,则直接指向这个字符串
其次,还需要知道一个原理,
在编译时就能确定的字符串,就会直接加入常量池中

String s1 = "ab";
String s2 = "ab"'
System.out.println(s1 == s2);
//答案为true

解析
首先JVM在编译时,执行到String s1 = “ab"这条语句时,会先去常量池中去找,看有没有这个字符串"ab”,如果有,则直接指向这个字符串,如果没有,则会在池中加入这个字符串,并指向这个字符串
当执行到String s2 = “ab”,时,JVM发现常量池中已经存在了这个字符串,然后将s2 指向此字符串
在Java中," == "比较的是两个对象的地址,此时s1 和s2 指向的都是同一个字符串,结果为true

String s1 = new String("ABC");

解析
我们都知道,一个对象的存储原理, 引用变量存储在栈中,真正的对象存储在堆中
而new关键字就是为对象开辟内存,只有在运行是才会执行new的作用,所以
在JVM编译时,也会去常量池中去找"ABC",没有,那么就会将"ABC"放入常量池
同时,在运行时,在堆中开辟一段内存来存储"ABC"
在执行这条语句的时,等于新建了两个对象,一个在常量池中,一个在堆中
此时的s1指向的是堆中的地址

intern()

下面进入正题
首先看一下菜鸟编程上是如何解释这个方法的
intern() 方法返回字符串对象的规范化表示形式。
它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
通俗的讲,字符串的规范化表示就是返回这个字符串在常量池中的地址

String s1 = "abc";
String s2 = s1.intern();
System.out.println(s1 == s2);
//true
//s1 , s2都指向同一个字符串,所以为true;

再来看一个

String s1 = new String("ABC");
String s2 = s1.intern();
System.out.println(s1 == s2);
//false

解析
执行第一条语句,会在常量池中条件"ABC",同时在堆中开辟内存来存放"ABC",
s1 指向的是堆中的地址,s2 是指向常量池中的地址

String s1 = new String("ABC");
String s2 = new String("ABC");
String s3 = "ABC";
System.out.println(s1 == s2);//false
System.out.println(s1.intern() == s3);//true

s1 和 s2 都是指向两个堆中不同的对象,所以地址也不同,结果为false
而执行到第三条语句时,发现常量池中已经存在了"ABC"这个字符串了,所以s3会直接指向常量池中的地址,同时s1.intern()就是返回他在常量池中的地址

再来看一个

String s1 = "A";
String s2 = s1 + "B";
String s3 = "AB";
System.out.println(s2 == s3);//false
System.out.println(s2.intern() == s3);//true

解析
执行s2 时,这不是一个编译时就能确定的对象,这是一个在运行时才能确定的字符创,所以相当于new 了一个,s2 指向堆中的地址
而执行到s3 时,发现此时的常量池中已经有了,所以s3指向常量池中的地址
所以第一个为false , 第2个为true

posted @   秋天Code  阅读(115)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示