1

私はシングルトンパターンを経験していました.以下は私のシングルトンクラスです..

    package CrackingSingleton;

public class SingletonObject {
    private static SingletonObject ref; 
    private SingletonObject () //private constructor
    {   
    }

    public  static synchronized   SingletonObject getSingletonObject()
    {if (ref == null)
    ref = new SingletonObject();
    return ref;
        }

    public Object clone() throws CloneNotSupportedException
    {throw new CloneNotSupportedException ();
    }
    }

そして、私はそれを壊す方法を試していました。以下は私のコードです...

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

public class CrackingSingleton {    
     public static void main(String[] args) throws ClassNotFoundException,
       IllegalArgumentException, SecurityException,
       InstantiationException, IllegalAccessException,
       InvocationTargetException {      
        //First statement retrieves the Constructor object for private constructor of SimpleSingleton class.
        Constructor pvtConstructor = Class.forName("CrackingSingleton.SingletonObject.java").getDeclaredConstructors()[0];
        //Since the constructor retrieved is a private one, we need to set its accessibility to true.
        pvtConstructor.setAccessible(true);
        //Last statement invokes the private constructor and create a new instance of SimpleSingleton class.
         SingletonObject  notSingleton1 = ( SingletonObject) pvtConstructor.newInstance(null);
         SingletonObject  notSingleton2 = ( SingletonObject) pvtConstructor.newInstance(null);
    }
}

しかし、上記のクラス CrackingSingleton を実行すると、エラーがスローされます...

Exception in thread "main" java.lang.ClassNotFoundException: CrackingSingleton.SingletonObject.java
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at CrackingSingleton.CrackingSingleton.main(CrackingSingleton.java:14)
4

3 に答える 3

3

.javaクラス名に追加しています。Javaクラス名には。は含まれません.java。したがって、コードは次のようになります。

Constructor pvtConstructor = Class.forName("crackingsingleton.SingletonObject").getDeclaredConstructors()[0];

パッケージ名を大文字にしないように変更したことに注意してください。

于 2012-04-23T16:57:52.003 に答える
1

This happens because you are asking for a wrong class. Which is by the way clearly stated in the stacktrace also.

// This should work
// There is no need to add .java or .class declaration. 
Class.forName("CrackingSingleton.SingletonObject")

That being said, then you might want to consider using ENUM singleton pattern.

于 2012-04-23T17:02:20.927 に答える
1

代わりにこれを試すことをお勧めします。enumはるかにシンプルで堅牢です。

package crackingSingleton;

public enum SingletonObject {
    INSTANCE;
}

package crackingSingleton;

import java.lang.reflect.Constructor;

public class CrackingSingleton {
    public static void main(String... args) throws Exception {
        //First statement retrieves the Constructor object for private constructor of SimpleSingleton class.
        Constructor pvtConstructor = crackingSingleton.SingletonObject.class.getDeclaredConstructors()[0];
        //Since the constructor retrieved is a private one, we need to set its accessibility to true.
        pvtConstructor.setAccessible(true);
        //Last statement invokes the private constructor and create a new instance of SimpleSingleton class.
        SingletonObject  notSingleton1 = ( SingletonObject) pvtConstructor.newInstance(null);
        SingletonObject  notSingleton2 = ( SingletonObject) pvtConstructor.newInstance(null);
    }
}

版画

Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
    at java.lang.reflect.Constructor.newInstance(Constructor.java:520)
    at crackingSingleton.CrackingSingleton.main(CrackingSingleton.java:12)
于 2012-04-23T17:29:12.587 に答える