Java实现Immutable Class要点

来源:互联网 发布:mp280清零软件 编辑:程序博客网 时间:2024/06/07 18:43

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

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

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

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

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

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

[java] view plaincopy
  1. Wrong way to write a constructor:  
  2. public final class MyImmutable {  
  3. private final int[] myArray;  
  4. public MyImmutable(int[] anArray) {  
  5. this.myArray = anArray; // wrong  
  6. }  
  7. public String toString() {  
  8. StringBuffer sb = new StringBuffer("Numbers are: ");  
  9. for (int i = 0; i < myArray.length; i++) {  
  10. sb.append(myArray[i] + " ");  
  11. }  
  12. return sb.toString();  
  13. }  
  14. }  
  15. // the caller could change the array after calling the  
  16. constructor.  
  17. int[] array = {1,2};  
  18. MyImmutable myImmutableRef = new MyImmutable(array) ;  
  19. System.out.println("Before constructing " + myImmutableRef);  
  20. array[1] = 5// change (i.e. mutate) the element  
  21. System.out.println("After constructing " + myImmutableRef);  
  22. Out put:  
  23. Before constructing Numbers are: 1 2  
  24. After constructing Numbers are: 1 5  
  25.   
  26.    
  27.   
  28. Right way to write an immutable class  
  29. Right way is to copy the array before assigning in the constructor.  
  30.   
  31. public final class MyImmutable {  
  32. private final int[] myArray;  
  33. public MyImmutable(int[] anArray) {  
  34. this.myArray = anArray.clone(); // defensive copy  
  35. }  
  36. public String toString() {  
  37. StringBuffer sb = new StringBuffer("Numbers are: ");  
  38. for (int i = 0; i < myArray.length; i++) {  
  39. sb.append(myArray[i] + " ");  
  40. }  
  41. return sb.toString();  
  42. }  
  43. }  
  44. // the caller cannot change the array after calling the constructor.  
  45. int[] array = {1,2};  
  46. MyImmutable myImmutableRef = new MyImmutable(array) ;  
  47. System.out.println("Before constructing " + myImmutableRef);  
  48. array[1] = 5// change (i.e. mutate) the element  
  49. System.out.println("After constructing " + myImmutableRef);  
  50. Out put:  
  51. Before constructing Numbers are: 1 2  
  52. After constructing Numbers are: 1 2  
原创粉丝点击