下面创建String对象的方式一样吗?
上述程序创建对象类似,为什么s1和s2引用对象一样,但是s3和s4不一样呢?
在java程序中,许多基本类型的字面常量会经常用到,例如2,3.11,“hyy”等。为了提升程序的运行效率,节省内存,java为八种基本数据类型(int float long double char byte boolean short)提供了常量池
池是编程中,常见的提高效率的一种方式。
例如:
家庭条件不是太好的人,每个月定期打生活费,但有时紧急情况,急需用钱,需要打电话找父母要,比较麻烦,费时间。
如果家里有矿,父母直接把一整年的生活费都放到卡里,随用随取,很方便,效率就更高。
常量池有很多,今天我们聚焦学习字符串常量池(StringTable)。
字符串常量池在JVM中是,StringTable类,实际上底层就是固定大小的HashTalble(一种搜索效率很高的数据结构,详细见【什么是哈希表(HashTable)? - CSDN App】)
好回到刚才提到的问题,为什么s1==s2?
s1和s2都是用“”双引号创建的String对象,这种创建方式的特点是,至多只会创建一个相同的对象
在最初创建“hello”时,首先会用StringTable(也就是字符串常量池)寻找是否有“hello”,
如果没有:
创建一个创建一个指向“hello”的对象,然后返回指向这个对象的引用。
如果有:
直接返回指向“hello”对象的引用。
而对于s3和s4这种new String对象的创建方式,特点是:
至少会创建一个对象(在堆区)。
因此,s3(s3创建了两个对象,一个在字符串常量池,一个在堆区)和s4(s4创建了一个对象,在堆区)分别都创建了至少一个对象,其引用,自然也就不一样。
关于字符串常量池的形象理解(看懂就会了):
注意虽然两种创建方式,一定会在常量池创建一个对象,但是两个对象是分开创建的,不是在常量池共用一个对象。
另外,关于字符串常量池,介绍一个方法:
intern()方法
观察这个程序:
如果理解前文所说的,s2==s3是false就很好理解了。
那么intern()是用来干嘛的呢?
英文就是“进入”的意思:
调用完这个方法后,我们发现,s2真的等于s3了!
这就是intern()方法的作用(手动入池):
可以把没有(有,就不塞)在常量池中的String对象,塞进字符串常量池。