Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Whats the best way to design a singleton class that could throw an exception?

Here I have a Singleton (using Bill Pugh's method, documented in Wiki for Singleton).

    private static class SingletonObjectFactoryHolder{
    //1  
        private static final ObjectFactory INSTANCE = new ObjectFactory();
    }

    private ObjectFactory() throws Exception{
    //2
            //create the factory
    }


    public static ObjectFactory getInstance(){
    //3
        return SingletonObjectFactoryHolder.INSTANCE;
    }

If an exception is thrown at 2, I would like to propagate it to the caller. However, I can't throw an exception from line 1.

So, is my only option to return a null object if the singleton object wasn't created correctly?

Thanks

P.S I do realize that this Singleton can break if its loaded via different classloaders or if loaded reflexively, but it's good enough for my purpose.

//UPDATE

I am curious, can I not rearrange my design as below to throw exceptions?

Also, I don't need any synchronization (the classloader guarantees that the static inner class will only loaded once and only when getInstance() is called). Thus, thread-safe and lazily-instantiated?

 private static class SingletonObjectFactoryHolder{
        //1  
           public static ObjectFactory getInstance() throws Exception{
         return new ObjectFactory();
           }
 }

 private ObjectFactory() throws Exception{
        //2
        //create the factory
 }


 public static ObjectFactory getInstance(){
        //3
    return SingletonObjectFactoryHolder.getInstance();
 }

Thanks again.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
169 views
Welcome To Ask or Share your Answers For Others

1 Answer

Use a static initializer and rethrow the Exception as ExceptionInInitializerError. Click the link to read the Javadoc, you'll see that it suits exactly for this particular functional requirement: handling exceptions during static initialization. A singleton is in fact nothing less or more than a statically and lazily initialized global object.

private static class SingletonObjectFactoryHolder{
    private static final ObjectFactory INSTANCE;
    static {
        try {
            INSTANCE = new ObjectFactory();
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }
}

No need for double checked locking idiom which is considered an anti-pattern and in some circumstances even unsafe.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...