http://d.hatena.ne.jp/SiroKuro/20080403/1207236878
なんとなく気になったので、Singleton を破壊するための TIPS を余談として提示してみます。
結局クラスが一意であることを利用してクラスを1対1に結びついた単一のオブジェクトを作ってるだけなんだから
証明を書くには余白が足りない - 西尾泰和のはてなダイアリー
結局、クラスが一意じゃなければ、Singleton は破壊できちゃうんですよね。
今回破壊する Singleton はこういうクラスです。いたってシンプル。
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
これを、こういうコードからロードしてみちゃったりします。だいぶ乱暴なことをしますね。
import java.io.*; class test { public static void main(String[] args) throws Exception { System.out.println(newInstance() == newInstance()); } private static Object newInstance() throws Exception { File file = new File("Singleton.class"); final byte[] data = new byte[(int)file.length()]; new FileInputStream(file).read(data, 0, data.length); return new ClassLoader() { public Class<?> destroySingleton() { return defineClass("Singleton", data, 0, data.length); } }.destroySingleton().getMethod("getInstance").invoke(null); } }
結果は "false"
defineClass のたびに、新しい Singleton クラスが返ってきます。
素人にはお勧めできない。
微妙にクラスが一意という条件は満たしていますが、1つのクラスファイルから複数個の Class をロードできる、という例でした。
追記
上記コードを
- private static Object newInstance() throws Exception { + private static Singleton newInstance() throws Exception { - return new ClassLoader() { + return (Singleton) new ClassLoader() {
のように変更すると、もちろんコンパイルは通るんですが、実行すると
Exception in thread "main" java.lang.ClassCastException: Singleton cannot be cast to Singleton at test.newInstance(test.java:10) at test.main(test.java:4)
という、世にも奇妙な例外を吐き出してきます。
やっぱり素人にはお勧めできない。
댓글 없음:
댓글 쓰기