重新认识不可变对象String

    我们在最初学习时,在Java中,String被列为复合性数据类型,但现在来看,其实他真正的是一个不可变类,而与之属于一类的还有Integer,Long,Double,Float,Boolean等对象。所有这些类都有一个共同的特性,就是不可变性。一旦这个类被初始化,他的状态不再变化。这些类都被设计成final类型的,这些类只有一个构造方法。一旦被构造出来,就再也无法修改其内部状态。

   这些作为原始数据类型的封装类,可以直接参与一些集合类的运算,比如,可以直接在一个String的list里面,将某个string给remove掉,可以将两个list做差集等等,总之,这些基本的不可构建类,对于一些集合操作jdk都已经帮我们封装好。但是我们自己定义的类,却不能拿起做差集和随便remove。

比如下面的代码,可以正确运行:

 

public class App {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("abcdefg");
		list.add("higklmn");
		System.out.println("before remove:"+list.size());
		list.remove("higklmn");
		System.out.println("after remove:"+list.size());
	}
}

 我举上面的例子是说明,这些不可变类,通常已经重写了默认的equals方法及hashcode方法,例子可能不太恰当,但这估计是JDK中唯一一类重写了equals和hashcode的类。但是下面的代码,却不能正常运行:

 

 

public class App {
	public static void main(String[] args) {
		List<AObject> list = new ArrayList<AObject>();
		list.add(new AObject(1,2));
		list.add(new AObject(3,4));
		System.out.println("before remove:"+list.size());
		list.remove(new AObject(3,4));
		System.out.println("after remove:"+list.size());
	}
	static class AObject{
		private int a;
		private int b;
		public AObject(int a,int b){
			this.a = a;
			this.b = b;
		}
	}
}

 这就是我们在写Java的时候,不能使用两个Object的==或者equals来判断对象是否相同的原因。

 

同时,通过以上的用法,可以看出,String和int等基本数据类型相差比较的,相反,String是一个类,是一种特殊的类。

 

线程安全

不可变类除了具有以上特性外,最重要的莫过于线程安全了。Java并发编程实战中告诉我们,除非使用同步,否则尽可能的使用不可变对象。因为不可变对象即使不使用同步技术也不会出现线程安全的问题。根据我个人的理解,使用不可变对象时,Java总能保证对象在初始化完毕后,才将对象发布出去,这样就不会出现失效数据,不会出现对象处于一种不安全的发布装。

 

如果我们也要用到jdk的集合类,我们可能也要写一些不可变类,但有一个原则,就是对象一旦创建,不能在修改其状态或者方法的值。如何创建不可变类,这里有一遍文章比较好,大家可以参考:Java的可变类与不可变类

 
对这类话题感兴趣?欢迎发送邮件至 donlianli@126.com
关于我:邯郸人,擅长Java,Javascript,Extjs,oracle sql。
更多我之前的文章,可以访问  我的空间

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值