不可变对象(Immutable Object)
作用:一旦创建,这个对象的(状态/值)不能被更改了
其内在成员变量的值就不能修改了。
含有:String BigInteger BIgDecimal等等,后用String做例子详细说明。
自己创建不可变对象的方法:
字符串修改
public class ArgumentPassing {
public static void changeValue(int a)
{
a = 10;
}
public static void changeValue(String s1)
{
s1 = "def";
}
public static void changeValue(StringBuffer s1)
{
s1.append("def");
}
public static void main(String[] args) {
int a = 5; //基本类型
String b = "abc"; //不可变对象
StringBuffer c = new StringBuffer("abc"); //可变对象
changeValue(a);
changeValue(b);
changeValue(c);
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
输出:
5
abc
abcdef
为什么输出的b为abc而不是abcdef呢,因为String类时不可变对象。
1.刚开始b指向abc内存区
2.传入changeValue()函数中,开始s1和b指向abc内存区
3.运行changeValue()函数中的代码,因为String类是不可变对象。
所以s1指向def内存区而b还是指向abc区。
字符串的修改方法比较:
初始:String a=“abc"
方法1:a=a+"def" 此方法由于String时不可变对象,会新建一个abcdef的空间,从而造成原abc空间浪费
方法2:利用StringBuffer/StringBuilder中的a.append("def") 此方法直接在abc空间上修改,不会造成空间浪费
通过下例可比较观察方法的速度。
import java.util.Calendar;
public class StringAppendTest {
public static void main(String[] args) {
int n = 50000;
Calendar t1 = Calendar.getInstance();
String a = new String();
for(int i=0;i<n;i++)
{
a = a + i + ",";
}
System.out.println(Calendar.getInstance().getTimeInMillis() - t1.getTimeInMillis());
Calendar t2 = Calendar.getInstance();
StringBuffer b = new StringBuffer("");
for(int i=0;i<n;i++)
{
b.append(i);
b.append(",");
}
System.out.println(Calendar.getInstance().getTimeInMillis() - t2.getTimeInMillis());
Calendar t3 = Calendar.getInstance();
StringBuilder c = new StringBuilder("");
for(int i=0;i<n;i++)
{
c.append(i);
c.append(",");
}
System.out.println(Calendar.getInstance().getTimeInMillis() - t3.getTimeInMillis());
}
}
输出:
7604
5
3
所以字符串的加法最好用StringBuilder中的append()方法