当前位置:首页 > 开发 > 编程语言 > Java > 正文

Java不可变类或对象详解(Immutable class)

发表于: 2014-05-11   作者:darrenzhu   来源:转载   浏览次数:
摘要: 如果某个对象在被创建后其状态就不能被修改,那么这个对象就称为不可变对象。线程安全性是不可变对象的固有属性之一,它们的不变性条件是由构造函数创建的,只要它们的状态不改变,那么这些不变性条件就能得以维持。不可变对象一定是线程安全的。 当满足以下条件时,对象才是不可变的: 1) 对象创建以后其状态就不能修改。 2) 对象的所有域都是final类型(当然像不可变String类型的域并不需要声明为fi

如果某个对象在被创建后其状态就不能被修改,那么这个对象就称为不可变对象。线程安全性是不可变对象的固有属性之一,它们的不变性条件是由构造函数创建的,只要它们的状态不改变,那么这些不变性条件就能得以维持。不可变对象一定是线程安全的。
当满足以下条件时,对象才是不可变的:
1) 对象创建以后其状态就不能修改。
2) 对象的所有域都是final类型(当然像不可变String类型的域并不需要声明为final)。
3) 对象是正确创建的(在对象的创建期间,this引用没有逸出)。

更多详细参考<Java Concurrency in Practice> 关于“不变性”的章节


Java实现Immutable Class要点

Java中很多class都是immutable,像String,Integer等,它们通常用来作为Map的key.

那么在实现自定义的Immutable的Class的时候,应该注意哪些要点呢?

a)Class 应该定义成final,避免被继承。

b)所有的成员变量应该被定义成final。

c)不要提供可以改变类状态(成员变量)的方法。【get 方法不要把类里的成员变量让外部客户端引用,当需要访问成员变量时,返回成员变量的copy】

d)构造函数不要引用外部可变对象。如果需要引用可以在外部改变值的变量,应该在构造函数里进行defensive copy。

Wrong way to write a constructor:

public final class MyImmutable {
	private final int[] myArray;
	public MyImmutable(int[] anArray) {
		this.myArray = anArray; // wrong
	}
	public String toString() {
		StringBuffer sb = new StringBuffer("Numbers are: ");
		for (int i = 0; i < myArray.length; i++) {
			sb.append(myArray[i] + " ");
		}
		return sb.toString();
	}
}


//the caller could change the array after calling the constructor.

int[] array = {1,2};
MyImmutable myImmutableRef = new MyImmutable(array) ;
System.out.println("Before constructing " + myImmutableRef);
array[1] = 5; // change (i.e. mutate) the element
System.out.println("After constructing " + myImmutableRef);


Output:
Before constructing Numbers are: 1 2
After constructing Numbers are: 1 5


Right way to write an immutable class
Right way is to copy the array before assigning in the constructor.

public final class MyImmutable {
	private final int[] myArray;
	public MyImmutable(int[] anArray) {
		this.myArray = anArray.clone(); // defensive copy
	}
	public String toString() {
		StringBuffer sb = new StringBuffer("Numbers are: ");
		for (int i = 0; i < myArray.length; i++) {
			sb.append(myArray[i] + " ");
		}
		return sb.toString();
	}
}


//the caller cannot change the array after calling the constructor.
int[] array = {1,2};
MyImmutable myImmutableRef = new MyImmutable(array) ;
System.out.println("Before constructing " + myImmutableRef);
array[1] = 5; // change (i.e. mutate) the element
System.out.println("After constructing " + myImmutableRef);


Output:
Before constructing Numbers are: 1 2
After constructing Numbers are: 1 2

Exercises:
1.What is Immutable class. How to make a Immutable class

2.If we make a class immutable and it has one List reference how do we make sure the list is not getting modified by other references.

3.Write a class that is Immutable.

4.Why do we make Immutable class final.

5.How do we declare setter and getter in immutable class, What is the need of Immutable class.

6.If we have date and timestamp class which is mutable and we want another lass which takes these two types and create a datetimestamp object how to make sure that it is immutable .

Java不可变类或对象详解(Immutable class)

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
Class 类是在Java语言中 定义一个特定类的实现。一个类的定义包含成员变量,成员方法,还有这个类实
Class 类是在Java语言中定义一个特定类的实现。一个类的定义包含成员变量,成员方法,还有这个类实
Class 类是在Java语言中定义一个特定类的实现。一个类的定义包含成员变量,成员方法,还有这个类实
Java Class文件中包含以下信息: ClassFile { u4 magic; //模数 u2 minor_version; //次版本号 u2 m
一、事例 1.1 Test.java public class Test { public static void main(String[] args) { System.ou
String is an immutable class in Java. An immutable class is simply a class whose instances ca
String is an immutable class in Java. An immutable class is simply a class whose instances ca
作为C语言的超集,面向对象成为Objective-C与C语言的最大区别,因此,对象是Objective-C中最重要的
类实例即对象。对象的初始化过程也就是类的实例化过程。 inside JVM作者Bill Venners关于对象初始化
类实例即对象。对象的初始化过程也就是类的实例化过程。 inside JVM作者Bill Venners关于对象初始化
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号