本人基础班菜鸟一只,如有大神请指教!最近上讲到String ,感到雨里雾里,一时难以理解,于是百般x于寻得一良贴特分享给大家。
首先在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的时候会看常量池中是否存在这样的值,如果存在则直接返回,不存在则往常量池中插入一个新的这样的值,然后返回。
————————————————
版权声明:本文为CSDN博主「谈-恋-爱」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tanlicheng1/article/details/80534534 |
|