`
qqdwll
  • 浏览: 136672 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java 中 immutable class 以及怎样实现immutable 类

    博客分类:
  • Java
阅读更多
原文 http://www.javapractices.com/topic/TopicAction.do?Id=29

Immutable objects are simply objects whose state (the object's data) cannot change after construction. Examples of immutable objects from the JDK include String and Integer.

Immutable objects greatly simplify your program, since they :

    * are simple to construct, test, and use
    * are automatically thread-safe and have no synchronization issues
    * do not need a copy constructor
    * do not need an implementation of clone
    * allow hashCode to use lazy initialization, and to cache its return value
    * do not need to be copied defensively when used as a field
    * make good Map keys and Set elements (these objects must not change state while in the collection)
    * have their class invariant established once upon construction, and it never needs to be checked again
    * always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state 。

Immutable objects have a very compelling list of positive qualities. Without question, they are among the simplest and most robust kinds of classes you can possibly build. When you create immutable classes, entire categories of problems simply disappear.

Make a class immutable by following these guidelines :

    * ensure the class cannot be overridden - make the class final, or use static factories and keep constructors private
    * make fields private and final
    * force callers to construct an object completely in a single step, instead of using a no-argument constructor combined with subsequent calls to setXXX methods (that is, avoid the Java Beans convention)
    * do not provide any methods which can change the state of the object in any way - not just setXXX methods, but any method which can change state
    * if the class has any mutable object fields, then they must be defensively copied when passed between the class and its caller

In Effective Java, Joshua Bloch makes this compelling recommendation :

"Classes should be immutable unless there's a very good reason to make them mutable....If a class cannot be made immutable, limit its mutability as much as possible."

It's interesting to note that BigDecimal is technically not immutable, since it's not final.

Example

import java.util.Date;

/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/
public final class Planet {

  public Planet (double aMass, String aName, Date aDateOfDiscovery) {
     fMass = aMass;
     fName = aName;
     //make a private copy of aDateOfDiscovery
     //this is the only way to keep the fDateOfDiscovery
     //field private, and shields this class from any changes that 
     //the caller may make to the original aDateOfDiscovery object
     fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
  }

  /**
  * Returns a primitive value.
  *
  * The caller can do whatever they want with the return value, without 
  * affecting the internals of this class. Why? Because this is a primitive 
  * value. The caller sees its "own" double that simply has the
  * same value as fMass.
  */
  public double getMass() {
    return fMass;
  }

  /**
  * Returns an immutable object.
  *
  * The caller gets a direct reference to the internal field. But this is not 
  * dangerous, since String is immutable and cannot be changed.
  */
  public String getName() {
    return fName;
  }

//  /**
//  * Returns a mutable object - likely bad style.
//  *
//  * The caller gets a direct reference to the internal field. This is usually dangerous, 
//  * since the Date object state can be changed both by this class and its caller.
//  * That is, this class is no longer in complete control of fDate.
//  */
//  public Date getDateOfDiscovery() {
//    return fDateOfDiscovery;
//  }

  /**
  * Returns a mutable object - good style.
  * 
  * Returns a defensive copy of the field.
  * The caller of this method can do anything they want with the
  * returned Date object, without affecting the internals of this
  * class in any way. Why? Because they do not have a reference to 
  * fDate. Rather, they are playing with a second Date that initially has the 
  * same data as fDate.
  */
  public Date getDateOfDiscovery() {
    return new Date(fDateOfDiscovery.getTime());
  }

  // PRIVATE //

  /**
  * Final primitive data is always immutable.
  */
  private final double fMass;

  /**
  * An immutable object field. (String objects never change state.)
  */
  private final String fName;

  /**
  * A mutable object field. In this case, the state of this mutable field
  * is to be changed only by this class. (In other cases, it makes perfect
  * sense to allow the state of a field to be changed outside the native
  * class; this is the case when a field acts as a "pointer" to an object
  * created elsewhere.)
  */
  private final Date fDateOfDiscovery;
}


分享到:
评论

相关推荐

    Java常用工具类

    Java常用工具类是Java开发中不可或缺的一部分,它们提供了一系列便捷的方法,帮助开发者高效地处理各种常见任务。在Java中,最著名的工具类库是`java.util`包,它包含了大量实用类,如集合、日期时间、数学计算、...

    JAVA 工具类 项目

    在Java编程中,工具类(Utility Class)是包含静态方法的类,这些方法通常执行某种通用操作或提供一些辅助功能。这些工具类可以极大地提高代码的可读性和可重用性,减少代码冗余,使得开发者能更专注于业务逻辑。在...

    50个左右的JAVA工具类,相对比较全

    在Java编程领域,工具类(Utility Class)是程序员日常工作中不可或缺的部分。这些工具类提供了许多通用功能,可以简化代码编写,提高开发效率。标题提到的"50个左右的JAVA工具类,相对比较全"表明这是一个集合了大量...

    ImmutableObjects

    在Java编程语言中,不可变对象(Immutable Objects)是一个重要的概念,尤其是在构建健壮、易于维护的应用程序时。本篇将基于提供的文件内容来深入探讨不可变对象的概念及其在Java中的应用。 #### 不可变对象定义 ...

    java常用的工具类

    3. **Java Collections Framework**: Java内置的集合框架包括List、Set、Map等接口,以及它们的实现类如ArrayList、HashSet、HashMap等。`Collections`工具类提供了许多操作集合的方法,如排序、填充、查找等。`...

    Java中static、this、super、final用法.doc

    `final`在设计模式中也常用于实现不可变对象,如Java的`String`类就是不可变的。例如: ```java final int MAX_VALUE = 100; // 定义一个不可更改的常量 final class Immutable { private final int value; ...

    有关于JAVA的一些PPT

    以上知识点涵盖了文件标题和内容中涉及的关于Java编程的基本概念和操作,包括面向对象的原理、类和对象的定义、构造器的使用、以及Java内存管理的基本概念。这些是Java编程中的基础知识点,对于初学者来说十分重要。

    java面向对象之final修饰符.docx

    总结,final关键字在Java中用于保证数据的不可变性、方法的不可重写以及类的不可继承,它是Java中实现封装性和安全性的关键工具。理解并恰当使用final,有助于编写更加稳定和易于维护的代码。在实际开发中,合理使用...

    Java搞懂的六个问题.txt

    通过以上六点,我们可以看到文档中虽然没有明确列出六个问题,但是已经涵盖了Java开发中非常重要的几个方面,包括字符串处理、不可变性、对象比较以及 `final` 关键字的使用等。这些知识点对于理解和编写高质量的...

    java英文对照表

    类(Class)是面向对象编程的基本单位,类路径(class path)指示Java运行时系统查找类的位置。集合(Collection)和列表(List)是存储多个对象的数据结构,而迭代器(Iterator)用于遍历这些集合。 编译器...

    JAVA面试题汇总.pdf

    JAVA面试题汇总文档中涵盖的IT知识点内容丰富,包含了面向对象编程的核心概念以及Java语言中的关键特性。以下是根据文档内容整理的知识点: 1. 面向对象的三大特性: - 封装(Encapsulation):隐藏对象的属性和...

    解决启动Azkaban报错问题:java.lang.NoSuchMethodError: com.google.common.collect.ImmutableMap.toImmutableMap

    在Java编程中,`NoSuchMethodError` 是一个常见的运行时异常,它表示在类加载时找到了该类,但在该类中却找不到特定方法的定义。这个问题通常发生在不同版本的库之间存在不兼容的情况,即在编译时使用的库版本包含了...

    Java语言程序设计中文ppt第十章(对象详解)

    不可变对象(immutable object)是一种一旦创建就不能再改变它的内容的对象,而不可变类(immutable class)是指该类的所有数据都是私有的且没有修改器。例如,Circle 类如果删掉前面的 set 方法,那么该类就变成不...

    java oracle并发官方教程

    Java中的每个线程都是Thread类的实例。线程共享进程资源,因此具有更高的效率,但同时也带来了线程间通信的问题。在Java中,可以通过以下两种方式来创建和启动线程: 1. 实现Runnable接口:创建一个实现了Runnable...

    详解Java编程中final,finalize,finally的区别

    Java编程中的`final`, `finalize`, 和`finally`是三个重要的关键字,它们各自在不同的场景下发挥着关键作用。理解这三个关键字的区别对于Java开发者来说至关重要,尤其是在面试中常常会被问及。 首先,`final`是一...

    java笔试面试题汇总

    - **描述**: 在一个`.java`源文件中可以包含多个类,但是只能有一个公共类(public class),并且该公共类的名字必须与文件名一致。 - **应用场景**: 当开发模块化较强的程序时,为了组织结构清晰,可能会在一个文件...

    Java问题与解答

    2. **数据抽象**:关注数据结构本身以及如何操作这些数据,如定义类和对象。 **优点:** - 提高代码的可读性和可维护性。 - 减少代码的复杂度。 - 有助于模块化设计。 #### 二、继承(Inheritance) **定义:** ...

    ikm_java_8.pdf

    通过以上分析,我们了解了Java 8中关于多线程安全的一些技巧、JavaScript表单验证的基本原理、如何在Servlet中读取初始化参数以及Swing组件类型的区别。这些知识点对于开发高质量的Java应用程序至关重要。

    Java编程实验内容.ppt

    Java的编译环境包括Java源文件、Java编译器、Java字节码、Java解释器、JIT编译器、Runtime系统、Class加载器、字节码验证器、Java类库、操作系统和硬件。Java虚拟机(JVM)是Java的核心,负责解释字节码和管理Java...

Global site tag (gtag.js) - Google Analytics