经常用String,但是对它的了解都是这儿看一点,那儿看一点,没有一次性的好好去了解它,这篇文章我会从应用的层面,好好地解剖一下String!
可以发现,String的开头字母是大写的,因此它本身是一个类.说到类,就不能不提实例化对象操作.
1,String类的实例化
实例化有两种方式,一种是通过new关键字调用构造函数完成,一种是直接赋值.那么这两种方式有什么区别呢?
在对以上问题解释之前,必须要明白一个重要概念,即一个字符串就是一个String类的匿名对象(即已经开辟了堆内存空间并可以直接使用的对象)
String str = "hello";
这段代码实际上就是把一个在堆中开辟好的堆内存空间的使用权给了str对象.
String str1 = "hello";
String str2 = "hello";
String str3 = "hello";
上述代码对应的内存操作是这样的:
这种直接用"="来实例化字符串的一个好处就是,如果堆内存中存在这个字符串,则不会另外再开辟一个空间,这样的设计成为共享设计.这种设计的思路是:在Java中形成一个对象池,在这个对象池中保存多个对象,新实例化的对象如果已经在对象池中定义了,则不再重新定义,而从池中取出来直接用.String就是采用了这种设计,所以当内容重复时,会将对象指向已存在的实例空间(堆内存).
再来看看这段代码:
String str1 = new String("hello");
String str2 = new String("hello");
String str3 = new String("hello");
它的内存处理是这样的:
即如果使用了new关键来创建String对象的话,不管堆内存中是否已经存在此内容,都会再另外开辟一个空间来存放新对象内容.
2,String的内容不可改变
在String类进行操作时,这个特点是必须明白的!我们来看以下代码:
public class Test{
public static void main(String []args){
String str = "hello";
str = "world";
System.out.println(str);
}
}
结果为:world
咋一看,str的内容不是改变了么!其实这只是表象来看看内存过程吧!
执行String str="hello"时,内存是这样的
接下来执行str="world"时,内存为:
可以看出,在堆内存中的内容实际上并没有改变,而是另外又开辟出了一个存放"world"的空间,而原来的"hello"则等待垃圾回收机制对其进行回收!
所以,针对String的这一特性,如果一串字符串需要反复改写,一定要避免使用String!!!
3,关于"=="和"equals"
其实明白了String的堆栈内存分配关系,这个就很好理解了.
只要记住一个规则就行:
*."=="比较基本数据类型内容,如果比较的是对象,则比较的是它们的堆内存地址
*."equals"用于比较对象内容.
PS:关于String的一些常用操作,我另外一篇博文会进行总结