java中String之常量池与对象

本文详细探讨了 Java 中 String 类的内部实现机制,包括常量池的概念、equals 方法的重写以及字符串比较的区别。通过具体代码示例展示了不同情况下字符串比较的结果。

最近一直在研究源码,今天把String类给看完了,基本上是把源码看了一遍(JDK1.8),所获得的收获还是可以的,但是看了归看了,俗话说的好好记性不如烂笔头,今天就写一写自己的心得体会。

首先在String类型在开发项目中用的是比较多的,大多数的都是在比较是否相等判断之类的,在String中重写了equals方法,先是比较地址,然后比较是否是是同一类型的对象,如果是则比较length,如果length相等则通过本身的value值(数组类型的)一个个的比较,都相等则返回true,否则为false。

在java中的运算符==会根据类型进行判断该比较什么,如果是对象类型的则会比较地址,如果是基本数据类型的则会比较其值,当然还有一种基本类型和对象类型的比较,下面我主要说java中的常量池。

在JDK1.8的版本中维护的有常量池这一说,(以前的版本我不知道,没看过),当我们通过字面量去赋值给String对象的时候,jvm会去先查看下在String类型的常量池中是否有这样的一个字符串,如果有则把引用返回,没有则新创建一个一样内容的字符串并将其引用返回,但是在String类型的常量池中同一时间只会存在一个内容一样的字符串,所以这也就保证了唯一性。

String s1="abc";
String s2="abc";

System.out.println(s1==s2);//true
System.out.println(s1.equals(s2));//true

String s3=new String("abc");
String s4=new String("abc");

System.out.println(s3==s4);//false
System.out.println(s3.equals(s4));//true

String s5=new String("abd");
String s6=s5;
System.out.println(s5==s6);//true

String s7="abcde";
String s8=s1+"de";
System.out.println(s7==s8);//false

String s9="abcd"+"e";
System.out.println(s7==s9);//true

String s10="abcdef";
String s11=s10.intern();
System.out.println(s10==s11);//true

首先说s1和s2,在给s1赋值的时候去常量池中查找,第一次初始化的常量池为空的,所以是没有的,则新创建一个abc放到常量池中,并把引用返回给s1,当s2也是这样的过程,在常量池中找到了,所以s1和s2指向相同的引用,即s1==s2和s1.equals(s2)都为true。

s3和s4是创建两个对象,在创建对象的时候是在堆里面开辟了一个空间,两个对象自然地地址空间就不相同,所以在s3==s4是为false,但是在equals比较内容的时候为true,因为其内容相等。但是再给s3和s4赋值的时候都是先去常量池中查找看是否有这样的内容,有的话拷贝一份内容出来进行赋值。

s5和s6,因为s6指向了s5的地址,所以是同一个地址空间,自然相等了。

s7和s8,s7因为赋值的是字面量常量,指向的是字符串常量池,而s8是由变量s1和字面量常量组成的,因为有s1变量无论和什么类型的进行+,所以会产生新的字符串,而这个新字符串会是new出来的,所以是在堆空间中,所以s7==s8是false。

s7和s9因为指向的都是一个常量池的字符串,又因为常量池中的字符串是唯一的,所以s7==s9。

s10和s11,使用intern的时候会看常量池中是否存在这样的值,如果存在则直接返回,不存在则往常量池中插入一个新的这样的值,然后返回。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值