java 不可变对象_Java多线程——不可变对象

不可变对象条件

对象需要满足一下三个条件才是不可变对象:

1、对象创建以后其状态就不能修改

2、对象所有域都是final类型

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

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

final关键字

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

@Slf4jpublic classImmutableExample1 {private final static Integer a = 1;private final static String b = "2";private final static Map map = newHashMap();static{

map.put(1, 2);

map.put(3, 4);

map.put(5, 6);

}public static voidmain(String[] args) {

map.put(1, 3);

log.info("{}", map.get(1));

}

}

虽然map声明为final对象,但是依然可以往里放入键值对。

Java提供常见不可变对象

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

@Slf4jpublic classImmutableExample2 {private static Map map =Maps.newHashMap();static{

map.put(1, 2);

map.put(3, 4);

map.put(5, 6);

map=Collections.unmodifiableMap(map);

}public static voidmain(String[] args) {

map.put(1, 3);

log.info("{}", map.get(1));

}

}

执行结果如下:

e6fe6ef40b682cbb0a2dccca13b4b75f.png

发现执行结果为抛出异常信息,不允许被修改。我们可以用这个方法来修饰不可变的集合对象。

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

public classCollections {//Suppresses default constructor, ensuring non-instantiability.

privateCollections() {

}private final Map extends K, ? extends V>m;

UnmodifiableMap(Map extends K, ? extends V>m) {if (m==null)throw newNullPointerException();this.m =m;

}

... ...publicV put(K key, V value) {throw newUnsupportedOperationException();

}publicV remove(Object key) {throw newUnsupportedOperationException();

}public void putAll(Map extends K, ? extends V>m) {throw newUnsupportedOperationException();

}public voidclear() {throw newUnsupportedOperationException();

}

... ...

}

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值