불변 객체

4255 단어
공유 대상이 안전하게 발표되려면 주로 두 가지 방법이 있는데 하나는 추가 동기화 방법이고 다른 하나는 대상을 변하지 않는 대상으로 하는 것이다.조건이 충족되면 객체는 변경될 수 없습니다.
  • 대상이 만들어진 후에는 상태를 수정할 수 없음
  • 대상의 모든 영역은final 유형
  • 대상이 올바르게 생성되었습니다(대상을 만드는 동안this 인용이 나오지 않음)
  • 객체를 안전하게 게시하고, 객체의 참조 및 객체의 상태가 다른 스레드에 동시에 표시되어야 하며, 올바르게 구성된 객체는 다음과 같은 방법으로 안전하게 게시할 수 있습니다.
  • 정적 초기화 함수에서 대상 인용 초기화
  • 대상의 인용을volatile 유형의 영역이나 AutomicReference 대상에 저장
  • 대상의 인용을 정확한 구조 대상의final 유형역에 저장
  • 대상의 인용을 잠금 보호된 영역에 저장
  • 불변 객체:
  • Declare the class as final so it can’t be extended.
  • Make all fields private so that direct access is not allowed.
  • Don’t provide setter methods for variables
  • Make all mutable fields final so that it’s value can be assigned only once.
  • Initialize all the fields via a constructor performing deep copy.
  • Perform cloning of objects in the getter methods to return a copy rather than returning the actual object reference.

  • 예:
    package com.journaldev.java;
    
    import java.util.HashMap;
    import java.util.Iterator;
    
    public final class FinalClassExample {
    
    	private final int id;
    	
    	private final String name;
    	
    	private final HashMap testMap;
    	
    	public int getId() {
    		return id;
    	}
    
    
    	public String getName() {
    		return name;
    	}
    
    	/**
    	 * Accessor function for mutable objects
    	 */
    	public HashMap getTestMap() {
    		//return testMap;
    		return (HashMap) testMap.clone();
    	}
    
    	/**
    	 * Constructor performing Deep 
    	 * @param i
    	 * @param n
    	 * @param hm
    	 */
    	
    	public FinalClassExample(int i, String n, HashMap hm){
    		System.out.println("Performing Deep  for Object initialization");
    		this.id=i;
    		this.name=n;
    		HashMap tempMap=new HashMap();
    		String key;
    		Iterator it = hm.keySet().iterator();
    		while(it.hasNext()){
    			key=it.next();
    			tempMap.put(key, hm.get(key));
    		}
    		this.testMap=tempMap;
    	}
    	
    	
    	/**
    	 * Constructor performing Shallow 
    	 * @param i
    	 * @param n
    	 * @param hm
    	 */
    	/**
    	public FinalClassExample(int i, String n, HashMap hm){
    		System.out.println("Performing Shallow  for Object initialization");
    		this.id=i;
    		this.name=n;
    		this.testMap=hm;
    	}
    	*/
    	
    	/**
    	 * To test the consequences of Shallow  and how to avoid it with Deep  for creating immutable classes
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		HashMap h1 = new HashMap();
    		h1.put("1", "first");
    		h1.put("2", "second");
    		
    		String s = "original";
    		
    		int i=10;
    		
    		FinalClassExample ce = new FinalClassExample(i,s,h1);
    		
    		//Lets see whether its copy by field or reference
    		System.out.println(s==ce.getName());
    		System.out.println(h1 == ce.getTestMap());
    		//print the ce values
    		System.out.println("ce id:"+ce.getId());
    		System.out.println("ce name:"+ce.getName());
    		System.out.println("ce testMap:"+ce.getTestMap());
    		//change the local variable values
    		i=20;
    		s="modified";
    		h1.put("3", "third");
    		//print the values again
    		System.out.println("ce id after local variable change:"+ce.getId());
    		System.out.println("ce name after local variable change:"+ce.getName());
    		System.out.println("ce testMap after local variable change:"+ce.getTestMap());
    		
    		HashMap hmTest = ce.getTestMap();
    		hmTest.put("4", "new");
    		
    		System.out.println("ce testMap after changing variable from accessor methods:"+ce.getTestMap());
    
    	}
    
    }
    

        

    좋은 웹페이지 즐겨찾기