字符串常量区
对于一个字符串的字面值为”hello”,如果说你要多次使用,如果对于这一个字符串字面值创建对象,那么很浪费内存,为此,java设计了字符串常量池,你就可以重用这一个字符串对象。
例子
看几个字符串比较的例子:
String a = "abc";//存放在字符串常量区
System.out.println(a=="abc");//true
String a = ” “,这种方式创建的字符串,会首先到字符串常量区看看有没有这个字符串,没有则创建一个字符串对象放到字符串常量区。后面那个直接申明的” ” ,也会到常量区看看,有的话,就都指向该字符串常量对象,所以结果为true。
String w = new String("hello");
System.out.println(w=="hello");//false
我们都知道new方式创建的对象都是在堆上的。那它创建的过程是什么样?
在常量池中查找是否有“hello”对象
有则返回对应的对象 没有则创建对应的实例对象
在堆中 new 一个 String(“abc”) 对象,这个堆中对象指向的是字符串常量区对象的地址
将堆中对象地址赋值给w,创建一个引用
这里w指向堆的引用覆盖了指向字符常量区的引用,所以一个是堆对象,一个是字符串常量区对象,地址肯定不同。
但是,我们如何通过w区引用字符串常量区的那个对象呢?就引出下面intern方法。
intern
该方法是,如果调用的字符串在常量区中存在,那么直接返回常量区的对象,如果没有,则把该对象添加到常量区,并返回引用,为什么要这样,保证对象的重用。
System.out.println(w.intern()=="hello");//true,这里的两个都是常量区的字符串对象