? ? 我们在最初学习时,在Java中,String被列为复合性数据类型,但现在来看,其实他真正的是一个不可变类,而与之属于一类的还有Integer,Long,Double,Float,Boolean等对象。所有这些类都有一个共同的特性,就是不可变性。一旦这个类被初始化,他的状态不再变化。这些类都被设计成final类型的,这些类只有一个构造方法。一旦被构造出来,就再也无法修改其内部状态。
? ?这些作为原始数据类型的封装类,可以直接参与一些集合类的运算,比如,可以直接在一个String的list里面,将某个string给remove掉,可以将两个list做差集等等,总之,这些基本的不可构建类,对于一些集合操作jdk都已经帮我们封装好。但是我们自己定义的类,却不能拿起做差集和随便remove。
比如下面的代码,可以正确运行:
?
class="java">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()); } }
?但是下面的代码,却不能正常运行:
?
?
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来判断对象是否相同的原因。
?
?
线程安全
不可变类除了具有以上特性外,最重要的莫过于线程安全了。Java并发编程实战中告诉我们,除非使用同步,否则尽可能的使用不可变对象。因为不可变对象即使不使用同步技术也不会出现线程安全的问题。根据我个人的理解,使用不可变对象时,Java总能保证对象在初始化完毕后,才将对象发布出去,这样就不会出现失效数据,不会出现对象处于一种不安全的发布装。
?
如果我们也要用到jdk的集合类,我们可能也要写一些不可变类,但有一个原则,就是对象一旦创建,不能在修改其状态或者方法的值。如何创建不可变类,这里有一遍文章比较好,大家可以参考:Java的可变类与不可变类
? 对这类话题感兴趣?欢迎发送邮件至donlianli@126.com 关于我:邯郸人,擅长Java,Javascript,Extjs,oracle sql。 更多我之前的文章,可以访问?我的空间?