不可变对象(immutable objects),后面文章我将使用immutable objects来代替不可变对象!
那么什么是immutable objects?什么又是mutable Objects呢?
immutable Objects就是那些一旦被创建,它们的状态就不能被改变的Objects,每次对他们的改变都是产生了新的immutable的对象,而mutable Objects就是那些创建后,状态可以被改变的Objects.
举个例子:String和StringBuilder,String是immutable的,每次对于String对象的修改都将产生一个新的String对象,而原来的对象保持不变,而StringBuilder是mutable,因为每次对于它的对象的修改都作用于该对象本身,并没有产生新的对象。
但有的时候String的immutable特性也会引起安全问题,这就是密码应该存放在字符数组中而不是String中的原因!
immutable objects 比传统的mutable对象在多线程应用中更具有优势,它不仅能够保证对象的状态不被改变,而且还可以不使用锁机制就能被其他线程共享。
实际上JDK本身就自带了一些immutable类,比如String,Integer以及其他包装类。为什么说String是immutable的呢?比如:java.lang.String 的trim,uppercase,substring等方法,它们返回的都是新的String对象,而并不是直接修改原来的对象。
如何在Java中写出Immutable的类?
要写出这样的类,需要遵循以下几个原则:
1)immutable对象的状态在创建之后就不能发生改变,任何对它的改变都应该产生一个新的对象。
2)Immutable类的所有的属性都应该是final的。
3)对象必须被正确的创建,比如:对象引用在对象创建过程中不能泄露(leak)。
4)对象应该是final的,以此来限制子类继承父类,以避免子类改变了父类的immutable特性。
5)如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身(该条可以归为第一条中的一个特例)
当然不完全遵守上面的原则也能够创建immutable的类,比如String的hashcode就不是final的,但它能保证每次调用它的值都是一致的,无论你多少次计算这个值,它都是一致的,因为这些值的是通过计算final的属性得来的!
另外,如果你的Java类中存在很多可选的和强制性的字段,你也可以使用建造者模式来创建一个immutable的类。
下面是一个例子:
public final class Contacts {
private final String name;
private final String mobile;
public Contacts(String name, String mobile) {
this.name = name;
this.mobile = mobile;
}
public String getName(){
return name;
}
public String getMobile(){
return mobile;
}
}
我们为类添加了final修饰,从而避免因为继承和多态引起的immutable风险。
上面是最简单的一种实现immutable类的方式,可以看到它的所有属性都是final的。
有时候你要实现的immutable类中可能包含mutable的类,比如java.util.Date,尽管你将其设置成了final的,但是它的值还是可以被修改的,为了避免这个问题,我们建议返回给用户该对象的一个拷贝,这也是Java的最佳实践之一。下面是一个创建包含mutable类对象的immutable类的例子:
public final class ImmutableReminder{
private final Date remindingDate;
public ImmutableReminder (Date remindingDate) {
if(remindingDate.getTime() < System.currentTimeMillis()){
throw new IllegalArgumentException("Can not set reminder” +
“ for past time: " + remindingDate);
}
this.remindingDate = new Date(remindingDate.getTime());
}
public Date getRemindingDate() {
return (Date) remindingDate.clone();
}
}
上面的getRemindingDate()方法可以看到,返回给用户的是类中的remindingDate属性的一个拷贝,这样的话如果别人通过getRemindingDate()方法获得了一个Date对象,然后修改了这个Date对象的值,那么这个值的修改将不会导致ImmutableReminder类对象中remindingDate值的修改。
使用Immutable类的好处:
1)Immutable对象是线程安全的,可以不用被synchronize就在并发环境中共享
2)Immutable对象简化了程序开发,因为它无需使用额外的锁机制就可以在线程间共享
3)Immutable对象提高了程序的性能,因为它减少了synchroinzed的使用
4)Immutable对象是可以被重复使用的,你可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。你可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。
immutable也有一个缺点就是会制造大量垃圾,由于他们不能被重用而且对于它们的使用就是”用“然后”扔“,字符串就是一个典型的例子,它会创造很多的垃圾,给垃圾收集带来很大的麻烦。当然这只是个极端的例子,合理的使用immutable对象会创造很大的价值。
分享到:
相关推荐
在Java编程中,不可变对象(Immutable Objects)是一种一旦创建后就不能被修改的对象。这种特性在多线程环境中尤其重要,因为不可变对象是线程安全的,它们不会因为并发修改而引发数据不一致的问题。Guava库是Google...
Java中的不可变类(immutable)是一种特殊的类,其对象一旦创建后,其状态就不能再发生变化。这类类在Java中有着重要的地位,特别是String类,它是Java中最常用的不可变类之一。不可变类的设计旨在提高安全性、效率...
在Java编程语言中,不可变对象(Immutable Objects)是一个重要的概念,尤其是在构建健壮、易于维护的应用程序时。本篇将基于提供的文件内容来深入探讨不可变对象的概念及其在Java中的应用。 #### 不可变对象定义 ...
Immutables是一个强大的Java库,专门用于创建不可变对象,并且提供了一个注解处理器来简化这一过程。在软件开发中,不可变对象是那些一旦创建就不能改变其状态的对象,这有助于提升程序的安全性、可预测性和并发性能...
流行的Java面试题之一是:什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immutable类型? 不可变对象,顾名思义是创建后不可以...
不可变对象(immutable object)是一种一旦创建就不能再改变它的内容的对象,而不可变类(immutable class)是指该类的所有数据都是私有的且没有修改器。例如,Circle 类如果删掉前面的 set 方法,那么该类就变成不...
在计算机科学中,“Immutable(不可变)”意味着一个对象一旦创建,其内部状态就不能被修改。对于集合来说,这就意味着一旦集合被初始化后,你就不能向其添加、删除或更改任何元素。这样的集合在多线程环境下特别...
本知识点将深入探讨Java多线程设计以及如何利用“不可变对象”(immutable objects)来避免多线程环境中的非安全问题。 一、Java多线程基础 1. 线程的创建:Java提供了两种创建线程的方式——继承Thread类和实现...
String 对象有一个非常重要的特点,即它是不可变的(immutable)。这意味着一旦创建了 String 对象,它的值就不能被改变。 在 Java 中,可以使用两种方式创建 String 对象:一种是使用字面值赋值方式,例如 `String...
Java中的不可变类型(Immutable Types) 不可变类型是那些一旦创建后就不能改变其状态的对象。例如,使用`final`关键字声明的变量。 ### 8. 垃圾收集(Garbage Collector) Java拥有自动垃圾收集器,它负责回收...
在编程领域,不可变对象(Immutable Object)是一种特殊类型的对象,一旦创建,其状态就不能被修改。这种设计模式在Java等编程语言中广泛应用于提高并发性能、保证数据安全以及简化编程逻辑。本篇文章将深入探讨如何...
Java中的不可变对象是编程实践中的一种重要概念,它是指一旦创建,对象的状态就不能再改变的类实例。不可变性在Java中广泛应用于如String、BigInteger和BigDecimal等基本类型,提供了许多优势,包括简化设计、减少...
不可变性带来的安全:不可变对象在作为参数传递给其他方法或类时,不会被意外修改,因此它们可以安全地用于公共API,避免了因外部修改而导致的错误。这与字符串常量池的工作原理类似,字符串一旦创建就不可更改,...
4. **设计原则**:在编写工具类时,通常遵循单例模式(Singleton)和不可实例化( Immutable)的原则。这意味着工具类只有一个全局访问点,且不允许通过构造函数创建实例,以确保其静态方法的独立性。 5. **线程...
Java常用工具类是Java开发中不可或缺的一部分,它们提供了一系列便捷的方法,帮助开发者高效地处理各种常见任务。在Java中,最著名的工具类库是`java.util`包,它包含了大量实用类,如集合、日期时间、数学计算、...
Java标准库中的String、Integer和BigDecimal类就是不变对象的典型例子,它们分别表示不可变的字符串、整数和大数。 1. **简化编程**:由于不变对象只能处于一种状态,它们在正确初始化后就不会进入不一致的状态。这...
这通常用于创建不可变对象,如Java集合框架中的ArrayList类的子类`Collections.unmodifiableList()`返回的列表就是final的,不能被修改。 ```java public final class ImmutableClass { private final String ...