我们知道Java中基本数据类型直接比较的是他们的值,String在Java中并不是基本数据类型,如果使用==比较两个字符串将是比较他们的地址;
如果是我们自定义的类比如是Persion p=new Persion(),在不重写equals的情况下,那么两个persion使用==相比较得到的结果肯定是false;
但是如果我们是new 两个String对象那么==会是怎么样的结果呢?
String compareOne=new String("abc");
String compareTwo=new String("abc");
很显然是false
但是如果我们是
String compareOne="abc";
String compareTwo="abc";
可以看到是true,
但是如果我们的连个字符串是如下的情况
String compareOne="abc";
String compareTwo=new String("abc").intern();
结果为true
那上面的情况有什么不同呢?
首先我们分析第一种,就是new String()的情况,我们知道使用new将会直接在堆中创建一个新的对象,
那么两次new出来的对象肯定是不同的,所以两个String的地址也就不相同。
对于第二种情况,为什么就返回true了呢?
因为两个字符串对象引用的是同一个对象”abc“,他们俩的地址是一样的也就不足奇怪了,
但是第三种情况第二个字符串对象在创建是使用了intern(),为什么使用intern后比较就相等了呢?
解释这个问题就需要我们了解Java创建字符一些基本机制。
我们在使用Java时字符串使用是极其频繁的,Java为了避免产生大量的String对象,Java使用了字符串常量池的机制,常量池中存放的都是字符串对象,它的闯将机制是:
创建字符串时会首先检查池中是否有字面值相等的字符串,如果有就不再创建而是直接返回池中该字符串的引用,如果没有就创建并放在池中,然后返回该字符串的引用
而intern会检查当前的对象在字符串池中是否有字面值相同的引用,如果有则返回池中的对象,如果没有则放到池中,在返回引用,这样就解释了第三种情况返回true的现象
使用intern的效率并不高,它虽然也在常量池中,但是它也需要通过equals的方法去比较,在常量池中查找是否窜在相同的字符串才能返回结果,显然这个过程不对比的通常不止一个字符串,而是多个字符串,效率显然要低一些,另外,它需要保证唯一,所以需要有锁的介入,这样效率就要打折了
通过这个问题告诉我们在平时对于字符串的赋值使用直接量赋值是比较好的习惯,
即String tempStr=”abc“