본문 바로가기

소프트웨어/Android/Java/Ndk

JavaEffective] singleton instance 훔치기

참고자료. 인사이트 출판 JavaEffective 2/E. Joshua Bloch


------------------------------------------


https://github.com/ManSung-Kim/mantdu/blob/master/javaEfeective/Je2PrivateClassInvoker.java


Singleton으로 구현된 Class의 Insatance를 훔치는(?) 방법을 시도해보고자 한다.

세상에나... Singleton은 무적일줄 알았는데 아니었나보다. 사실 이 내용은 Java Effective의 규칙은 아니고 "규칙3 Singletone Pattern에 관한" 내용 중에서 이러한 위험이 있으니 Singleton은 ~~하게 구현해라!! 하는 내용중에 나오는 인용자료이다.

읽고 조금 충격먹어서 따로 쓰고있다.



(참고소스 출처 http://stackoverflow.com/questions/4081227/singleton-pattern)

소스

package com.example.javaeffective;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import android.util.Log;

public class Je2PrivateClassInvoker {
	
	public Je2PrivateClassInvoker() {
		
		// origin
		PrivateSingleton originInstance = PrivateSingleton.getInstance();
		Log.d("mstag","Origin1 : "+originInstance.getTest());
		PrivateSingleton originInstance2 = PrivateSingleton.getInstance();
		Log.d("mstag","Origin2 : "+originInstance2.getTest());
		
		
		// invoke
		Constructor con = PrivateSingleton.class.getDeclaredConstructors()[0];
		con.setAccessible(true);
		try {
			PrivateSingleton newInstance1 = (PrivateSingleton) con.newInstance();
			Log.d("mstag","invoke : "+newInstance1.getTest());
		} catch (Exception e) {
			
		}
	}

}

class PrivateSingleton {
	private static final PrivateSingleton pInstance = new PrivateSingleton();
	
	public static PrivateSingleton getInstance() {
		return pInstance;
	}
	
	public String getTest() {
		return ""+this;
	}
}

소스끝


위의 소스를 보면 PrivateSingleton Class는  getInstance()를 사용하는 Singleton Class다. 평소에도 Singleon을 쓸때면 이러한 구조로 사용했는데, 이 방식은 Construct Class를 이용해서 새로운 instance를-그러니깐 주소가 다른 새로운 객체를- 생성할 수 있게 해준다. 와우




 위의 로그는 소스를 돌렸을때의 출력 모습이다. Origin1과 2는 getInstance를 사용하였기 때문에 같은 주소를 참조하고 있고, 마지막 인스턴스는 invoke된 새로운 주소를 참조하고있다.



그렇다면 이런 구조 말고 어떤 구조로 Singletone을 사용해야 할지는 다음번에 ..