
正文
JAVA核心技术I---JAVA基础知识(不可变对象和字符串)
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
一:不可变对象不可变对象(Immutable Object)
–一旦创建,这个对象(状态/值)不能被更改了–其内在的成员变量的值就不能修改了。
–典型的不可变对象
• 八个基本型别的包装类的对象
• String,BigInteger和BigDecimal等的对象
可变对象(Mutable Object)
–普通对象
(一)普通对象:可修改值 //普通对象
genobj go = new genobj();
genobj go2 = go; //两个指针指向一个对象 System.out.println(go.getnumber());
System.out.println(go2.getnumber());
go2.setnumber(); System.out.println(go.getnumber());
System.out.println(go2.getnumber());
if(go==go2) {
System.out.println("obj1==obj2");
}
obj1==obj2
(二)不可变对象,不允许修改值 //8个基本包装类
Integer I1=;
Integer I2=I1; System.out.println(I1);
System.out.println(I2); if(I1==I2) {
System.out.println("I1==I2");
} I2 = ; //修改值
System.out.println(I1);
System.out.println(I2);
if(I1==I2) {
System.out.println("I1==I2");
}else {
System.out.println("I1!=I2");
}
//发现原来的内存地址的值I1并没有修改,还是12,只是修改了对象指针I2的指向,指向13的内存
I1==I2I1!=I2
(三)在函数参数中体现不可变对象 String a = new String("abc");
String b = a;
System.out.println(b);
a = "def";
System.out.println(b);
abc
abc
函数修改
public static void main(String[] args) {
String a = new String("abc");
System.out.println(a);
change(a);
System.out.println(a);
} public static void change(String b) {
b = "def";
}
abc
abc
不可变对象(Immutable Object)
–一旦创建,这个对象(状态/值)不能被更改了–其内在的成员变量的值就不能修改了。
–典型的不可变对象
• 八个基本型别的包装类的对象
• String,BigInteger和BigDecimal等的对象
可变对象(Mutable Object)
–普通对象
//普通对象
genobj go = new genobj();
genobj go2 = go; //两个指针指向一个对象 System.out.println(go.getnumber());
System.out.println(go2.getnumber());
go2.setnumber(); System.out.println(go.getnumber());
System.out.println(go2.getnumber());
if(go==go2) {
System.out.println("obj1==obj2");
}
obj1==obj2
(二)不可变对象,不允许修改值 //8个基本包装类
Integer I1=;
Integer I2=I1; System.out.println(I1);
System.out.println(I2); if(I1==I2) {
System.out.println("I1==I2");
} I2 = ; //修改值
System.out.println(I1);
System.out.println(I2);
if(I1==I2) {
System.out.println("I1==I2");
}else {
System.out.println("I1!=I2");
}
//发现原来的内存地址的值I1并没有修改,还是12,只是修改了对象指针I2的指向,指向13的内存
I1==I2I1!=I2
(三)在函数参数中体现不可变对象 String a = new String("abc");
String b = a;
System.out.println(b);
a = "def";
System.out.println(b);
abc
abc
函数修改
public static void main(String[] args) {
String a = new String("abc");
System.out.println(a);
change(a);
System.out.println(a);
} public static void change(String b) {
b = "def";
}
abc
abc
//8个基本包装类
Integer I1=;
Integer I2=I1; System.out.println(I1);
System.out.println(I2); if(I1==I2) {
System.out.println("I1==I2");
} I2 = ; //修改值
System.out.println(I1);
System.out.println(I2);
if(I1==I2) {
System.out.println("I1==I2");
}else {
System.out.println("I1!=I2");
}
//发现原来的内存地址的值I1并没有修改,还是12,只是修改了对象指针I2的指向,指向13的内存
I1==I2I1!=I2
String a = new String("abc");
String b = a;
System.out.println(b);
a = "def";
System.out.println(b);
abc
abc
函数修改
public static void main(String[] args) {
String a = new String("abc");
System.out.println(a);
change(a);
System.out.println(a);
} public static void change(String b) {
b = "def";
}
abc
abc

不可变对象,也是传指针(引用)
由于不可变,临时变量指向新内存,外部实参的指针不改动
(四)如何创建一个不可变对象–immutable对象是不可改变,有改变,请clone/new一个对象进行修改
–所有的属性都是final和private的
–不提供setter方法
–类是final的,或者所有的方法都是final
–类中包含mutable对象,那么返回拷贝需要深度clone
(五)不可变对象优缺点不可变对象(Immutable Object)
优点
–只读,线程安全
–并发读,提高性能
–可以重复使用
缺点
–制造垃圾,浪费
二:字符串字符串是Java使用最多的类,是一种典型的不可变对象
String定义有2种
–String a = “abc”; //常量赋值,栈分配内存
–String b = new String(“abc”); //new对象,堆分配内存
字符串内容比较:equals方法
是否指向同一个对象:指针比较==
Java 常量池(Constant Pool)
–保存在编译期间就已经确定的数据
–是一块特殊的内存
–相同的常量字符串只存储一份,节省内存,共享(栈中,不是堆中)
(一)字符串加法String a=“abc”;
a = a+“def”; //由于String不可修改,效率差。
–immutable对象是不可改变,有改变,请clone/new一个对象进行修改
–所有的属性都是final和private的
–不提供setter方法
–类是final的,或者所有的方法都是final
–类中包含mutable对象,那么返回拷贝需要深度clone
不可变对象(Immutable Object)
优点
–只读,线程安全
–并发读,提高性能
–可以重复使用
缺点
–制造垃圾,浪费
二:字符串字符串是Java使用最多的类,是一种典型的不可变对象
String定义有2种
–String a = “abc”; //常量赋值,栈分配内存
–String b = new String(“abc”); //new对象,堆分配内存
字符串内容比较:equals方法
是否指向同一个对象:指针比较==
Java 常量池(Constant Pool)
–保存在编译期间就已经确定的数据
–是一块特殊的内存
–相同的常量字符串只存储一份,节省内存,共享(栈中,不是堆中)
(一)字符串加法String a=“abc”;
a = a+“def”; //由于String不可修改,效率差。
字符串是Java使用最多的类,是一种典型的不可变对象
String定义有2种
–String a = “abc”; //常量赋值,栈分配内存
–String b = new String(“abc”); //new对象,堆分配内存
字符串内容比较:equals方法
是否指向同一个对象:指针比较==
Java 常量池(Constant Pool)
–保存在编译期间就已经确定的数据
–是一块特殊的内存
–相同的常量字符串只存储一份,节省内存,共享(栈中,不是堆中)
String a=“abc”;
a = a+“def”; //由于String不可修改,效率差。

使用StringBuffer/StringBuilder类的append方法进行修改(原地修改,扩张)
StringBuffer/StringBuilder 的对象都是可变对象
StringBuffer(同步,线程安全,修改快速),
StringBuilder(不同步,线程不安全,修改更快)
int n = ;
Calendar t1 = Calendar.getInstance();
String a = new String();
for(int i=;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=;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=;i<n;i++)
{
c.append(i);
c.append(",");
}
System.out.println(Calendar.getInstance().getTimeInMillis() - t3.getTimeInMillis());
字符串append操作速度:StringBuilder>StringBuffer>String
(二)字符串函数传递 public static void changeValue(int a)
{
a = ;
}
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 = ; //基本类型
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);
}
三:StringBuffer和StringBuilder比较StringBuffer(字符串加减,同步,性能好)
StringBuilder(字符串加减,不同步,性能更好)
StringBuffer/StringBuilder: 方法一样,区别在同步
–append/insert/delete/replace/substring
–length 字符串实际大小,capacity字符串占用空间大小空间大小为实际大小加一,再两倍
–trimToSize(): 去除空隙,将字符串存储压缩到实际大小
–如有大量append,事先预估大小,再调用相应构造函数
public static void changeValue(int a)
{
a = ;
}
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 = ; //基本类型
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);
}
StringBuffer(字符串加减,同步,性能好)
StringBuilder(字符串加减,不同步,性能更好)
StringBuffer/StringBuilder: 方法一样,区别在同步
–append/insert/delete/replace/substring
–length 字符串实际大小,capacity字符串占用空间大小空间大小为实际大小加一,再两倍
–trimToSize(): 去除空隙,将字符串存储压缩到实际大小
–如有大量append,事先预估大小,再调用相应构造函数






