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 should work
// There is no need to add .java or .class declaration. 
Class.forName("CrackingSingleton.SingletonObject")

话虽如此,那么您可能需要考虑使用ENUM 单例模式

于 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 回答