ufk
ufk

Reputation: 32144

singleton using enum

I read a lot on stackoverflow regarding the creation of singleton classes using enum. I must have missed something because i can't reach the INSTANCE anywhere.

this is my code:

public class UserActivity {

    private DataSource _dataSource;
    private JdbcTemplate _jdbcTemplate;

    static enum Singleton {
        INSTANCE;

        private static final UserActivity singleton = new UserActivity();

        public UserActivity getSingleton() {
            return singleton;
        }
    }

    public UserActivity() {
        this._dataSource = MysqlDb.getInstance().getDataSource();
        this._jdbcTemplate = new JdbcTemplate(this._dataSource);
    }

    public void dostuff() {
     ...
    }
}

and outside I'm trying to do

UserActivity.INSTANCE.getSingleton()

or

UserActivity.Singleton.

but eclipse's code completion doesn't find anything

thanks!

Upvotes: 24

Views: 18805

Answers (3)

Mr_and_Mrs_D
Mr_and_Mrs_D

Reputation: 34086

public class UserActivity {

    private DataSource _dataSource;
    private JdbcTemplate _jdbcTemplate;

    private static enum Singleton { // private, why not
        INSTANCE;

        private static final UserActivity singleton = new UserActivity();

        public UserActivity getSingleton() {
            return singleton;
        }
    }

    private UserActivity() { // private !!(*)
        this._dataSource = MysqlDb.getInstance().getDataSource();
        this._jdbcTemplate = new JdbcTemplate(this._dataSource);
    }


    public static UserActivity getInstance() {
     return UserActivity.Singleton.INSTANCE.getSingleton();
    } 

    public void dostuff() {
     ...
    }
}

and call UserActivity.getInstance().doStuff();

You can't call the constructor (*) and you can only get an instance of your UserActivity() class via the INSTANCE in the private enum - which is guaranteed to be created once and only once

Upvotes: 1

Stephen C
Stephen C

Reputation: 719709

The trick is to make the enum itself the singleton. Try this:

public enum UserActivity {
    INSTANCE;

    private DataSource _dataSource;
    private JdbcTemplate _jdbcTemplate;

    private UserActivity() {
        this._dataSource = MysqlDb.getInstance().getDataSource();
        this._jdbcTemplate = new JdbcTemplate(this._dataSource);
    }

    public void dostuff() {
     ...
    }
}

// use it as ...
UserActivity.INSTANCE.doStuff();

Upvotes: 52

Jon Skeet
Jon Skeet

Reputation: 1504052

INSTANCE is a member of Singleton, not of UserActivity - so you'd need:

UserActivity.Singleton.INSTANCE.getSingleton();

However, you haven't actually made UserActivity a singleton - normally you'd make the type itself an enum, not embed an enum within the type...

Upvotes: 13

Related Questions