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

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

    博客分类:
  • Java
阅读更多

如果某个对象在被创建后其状态就不能被修改,那么这个对象就称为不可变对象。线程安全性是不可变对象的固有属性之一,它们的不变性条件是由构造函数创建的,只要它们的状态不改变,那么这些不变性条件就能得以维持。不可变对象一定是线程安全的。
当满足以下条件时,对象才是不可变的:
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语言程序设计中文ppt第十章(对象详解)

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

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

    总结起来,`final`用于声明不变量、方法和类,保证其不可变性或不可扩展性;`finalize`是为了在对象被回收前执行清理工作,但使用需谨慎;而`finally`则是异常处理的关键,确保了关键代码段的执行,特别是在资源管理...

    Java笔记PDF版含图片

    - **不可变对象 (Immutable Object):** 不可变对象是指创建后其状态就不能改变的对象。String类就是一个典型的不可变对象。 #### 六、常用类与数据结构 **数字类:** - **BigInteger/BigDecimal:** BigInteger和...

    stati、thi、supe、final关键字详解

    final class ImmutableClass { // 不可继承的类 private int value; ImmutableClass(int value) { this.value = value; } } ``` 总结,static、this、super和final是Java编程中非常重要的关键字。static用于...

    javafinal和static总结.docx

    这对于创建不可变对象(immutable object)非常重要。 #### 二、final的具体应用 ##### 1. final类 - **定义**:当一个类被声明为final时,该类不能被其他类继承。 - **目的**: - 避免子类对父类的实现细节进行...

    Java问题与解答

    - **String 类**:不可变(immutable),一旦创建就不能更改。 #### 六、int 和 Integer 的区别 - **int**:基本数据类型,直接存储数值。 - **Integer**:`int` 的包装类,可以转换为 `int` 值,支持 `null`。 *...

    Java的六大问题你都懂了吗

    `String`类被设计成不可变(immutable)类,这意味着一旦创建,其内容就不能更改。例如,对于表达式 `s = s + " world!"`,`s`原本指向一个内容为"Hello"的字符串对象,但在执行加法操作后,`s`不再指向原来的对象,...

    Java常见面试题(含答案)

    - `String` 类型在 Java 中是不可变的(immutable),这意味着一旦创建了一个字符串对象,其内容就不能被改变。 - 字符串对象存储在字符串常量池中,以提高效率。 - `String` 类提供了丰富的字符串操作方法,如`...

    通过实例解析java String不可变性

    Java 中的 String 类是一种不可变对象,它的不可变性是通过实例解析来实现的。下面我们将通过实例解析来详细介绍 Java 中 String 的不可变性。 一、不可变模式(Immutable Pattern) 在并行软件开发过程中,同步...

    Java初学者都必须理解的问题

    `String`类被设计为不可变(immutable)类,这意味着一旦创建了一个`String`对象,其内容就不能被更改。 **示例代码分析:** ```java String s = "Hello"; s = s + "world!"; ``` 这段代码中,`s`最初指向一个...

    2012java面试题全攻略.doc

    它代表了字符序列,并且是不可变的(immutable),这意味着一旦创建了一个字符串,就不能改变它的内容。这种设计提高了字符串在多线程环境下的安全性,同时也使得字符串可以用作HashMap的键,因为它们的哈希码不会在...

    Java面试125面试题和答案

    `String`类是不可变的(immutable),这意味着一旦创建了一个`String`对象,其内容就不能被更改。 **应用举例** 比较String与StringBuffer的差异: ```java String s1 = "Hello"; s1.concat("World"); // 不改变...

    java源码解读由浅入深.pdf

    `String`类在Java中是一个不可变类(immutable class),这意味着一旦创建了一个`String`对象,它的内容就不能改变。这种设计带来了诸多好处,包括安全性提高、多线程环境下的天然线程安全以及能够有效地利用内存...

    java经典总结

    `String` 类在Java中被设计为不可变的(immutable),这意味着一旦一个 `String` 对象被创建后,它的内容就不能更改。这种设计有利于提高性能和安全性。 例如: ```java String s = "Hello"; s = s + " world!"; `...

    JAVA葵花宝典

    它是不可变的(immutable),即一旦创建就不能改变其内容。 #### 三、int与Integer的区别 - **int**:是Java的基本数据类型之一,占用4个字节。 - **Integer**:是`int`的封装类,实现了对`int`的一些额外功能支持...

    有关Java String常用方法的总结.docx

    `String`类是Java中最基础也是最重要的数据类型之一,在Java中被定义为一个不可变类(immutable class),这意味着一旦一个`String`对象创建之后,其内容就不能再被修改。`String`类提供了丰富的内置方法来操作字符...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第二阶段20讲、多线程不可变对象设计模式Immutable-下.mp4 │ 高并发编程第二阶段21讲、多线程Future设计模式详细介绍-上.mp4 │ 高并发编程第二阶段22讲、多线程Future设计模式详细介绍-下.mp4 │...

    软件开发编码规范.doc

    保护包和不可变对象(immutable)是提高安全性的有效手段。序列化过程要小心,避免敏感信息泄露。最后,及时清除不再需要的敏感信息,降低数据泄露的风险。 总的来说,良好的编码规范是软件开发的基石,它能帮助...

    Scala程序设计(第2版)

    12.1 通用、可变、不可变、并发以及并行集合 288 12.1.1 scala.collection包 289 12.1.2 collection.concurrent包 290 12.1.3 collection.convert包 291 12.1.4 collection.generic包 291 12.1.5 ...

Global site tag (gtag.js) - Google Analytics