Java多线程——不可变对象

不可变对象条件

对象须要知足一下三个条件才是不可变对象:工具

一、对象建立之后其状态就不能修改this

二、对象全部域都是final类型spa

三、对象是正确建立的(对象在建立期间,this引用没有溢出)code

简而言之就是将类声明为final,将全部的成员声明为私有的,对变量不提供set方法。将全部可变的成员声明为final。在get方法中不返回对象自己,而是克隆对象的拷贝。(可参考String类)。对象

final关键字

final关键字可修饰类、方法和变量。在修饰类时,这个类是不容许被继承。final类中的方法会被隐式的被指定为final方法。修饰方法是为了锁定方法不被继承类修改,即final方法不容许被修改,一个类的private方法会被隐式指定为final类型。final修饰变量可分为两种状况。1、修饰基本数据类型时,一旦被final修饰,这个变量的数值就不能被修改了。2、修饰引用类型变量时,则是让它在初始化以后就不能指向其余对象(可修改该引用变量的成员变量)。例如:blog

@Slf4j
public class ImmutableExample1 {
 
    private final static Integer a = 1;
    private final static String b = "2";
    private final static Map<Integer, Integer> map = new HashMap();
 
    static {
        map.put(1, 2);
        map.put(3, 4);
        map.put(5, 6);
    }
 
    public static void main(String[] args) {
        map.put(1, 3);
        log.info("{}", map.get(1));
    }
}

虽然map声明为final对象,可是依然能够往里放入键值对继承

Java提供常见不可变对象

Collections.unmodifiableXXX:Collection、List、Set、Map等。rem

@Slf4j
public class ImmutableExample2 {
 
    private static Map<Integer, Integer> map = Maps.newHashMap();
 
    static {
        map.put(1, 2);
        map.put(3, 4);
        map.put(5, 6);
        map = Collections.unmodifiableMap(map);
    }
 
    public static void main(String[] args) {
        map.put(1, 3);
        log.info("{}", map.get(1));
    }
 
}

执行结果以下:get

 

发现执行结果为抛出异常信息,不容许被修改。咱们能够用这个方法来修饰不可变的集合对象。源码

查看源码的主要方法实现:

public class Collections {
    // Suppresses default constructor, ensuring non-instantiability.
        private Collections() {
        }
 
        private final Map<? extends K, ? extends V> m;
 
        UnmodifiableMap(Map<? extends K, ? extends V> m) {
            if (m==null)
                throw new NullPointerException();
            this.m = m;
        }
 
        ... ...
 
        public V put(K key, V value) {
            throw new UnsupportedOperationException();
        }
        public V remove(Object key) {
            throw new UnsupportedOperationException();
        }
        public void putAll(Map<? extends K, ? extends V> m) {
            throw new UnsupportedOperationException();
        }
        public void clear() {
            throw new UnsupportedOperationException();
        }
 
        ... ...
 
}

其实就是将put方法等直接抛出异常,防止修改。

其余工具提供的不可变对象

Googel经常使用的工具包Guava一样也提供了不少不可变对象的方法如 ImmutableXXX:Collection、List、Set、Map等。

相关文章
相关标签/搜索