一 基本概念
可變類和不可變類(Mutable and Immutable Objects)的初步定義:
可變類:當獲得這個類的一個實例引用時,可以改變這個實例的內容。
不可變類:不可變類的實例一但創建,其內在成員變量的值就不能被修改。其中String類就是不可變類的經典應用。
二 例子
package cn.xy.test;
public class StringTest
{
/**
* a的值在編譯時就被確定下來,故其值"xy"被放入String的駐留池(駐留池在堆中)並被a指向。
* b的值在編譯時也被確定,那麼b的值在String的駐留池中找是否有等於"xy"的值,有的話也被b指向。
* 故兩個對象地址一致
* @return true
*/
public static Boolean testString1()
{
String a = "xy";
String b = "xy";
return a == b;
}
/**
* b的值在是兩個常量相加,編譯時也被確定。
* @return true
*/
public static Boolean testString2()
{
String a = "xyy";
String b = "xy" + "y";
return a == b;
}
/**
* b的值為一個變量和一個常量相加,無法編譯時被確定,而是會在堆裡新生成一個值為"abc"的對象
* @return false
*/
public static Boolean testString3()
{
String a = "xyy";
String b = "xy";
b = b + "y";
return a == b;
}
/**
* b的值都無法編譯時被確定,而是會在堆裡分別新生成一個對象叫"xyy"。
* @return false
*/
public static Boolean testString4()
{
String a = "xyy";
String b = "xy".concat("y");
return a == b;
}
/**
* new String()創建的字符串不是常量,不能在編譯期就確定,所以new String() 創建的字符串不放入常量池中,它們有自己的地址空間。
* a,b的值都無法編譯時被確定,會在堆裡分別新生成一個值為"xy"的對象。
* @return fasle
*/
public static Boolean testString5()
{
String a = new String("xy");
String b = new String("xy");
return a == b;
}
/**
* intern()把駐留池中"xy"的引用賦給b。
* @return true
*/
public static Boolean testString6()
{
String a = "xy";
String b = new String("xy");
b = b.intern();
return a == b.intern();
}
/**
* String不可變性的體現
*/
String str = "xy";
public String chage(String str)
{
str = "xyy";
return str;
}
/**
* 一般引用類型的可變性(傳值的時候把地址傳過去,相當於把倉庫的要是交給方法,方法拿到鑰匙去移動倉庫裡的東西)
*/
Person p = new Person("xy");
public String changePerson(Person p)
{
p.setName("xyy");
return p.toString();
}
public static void main(String[] args)
{
print(testString1()); // true
print(testString2()); // true
print(testString3()); // fasle
print(testString4()); // false
print(testString5()); // false
print(testString6()); // true
StringTest t = new StringTest();
print(t.str); // xy
print(t.chage(t.str)); // xxy
print(t.str); // xy
print(t.p.toString()); //xy
print(t.changePerson(t.p)); //xyy
print(t.p.toString()); //xyy
}
public static void print(Object o)
{
System.out.println(o);
}
}