Java: singleton from base class - java

Lets assume we've got base class:
public class Base {
public Base(int i) {
/* ... */
}
/* ... */
}
We want to create singleton based on this class. The problem is that class have public constructor, so extending it will result in singleton having public constructor, too:
public class SingletonBase extends Base {
private static final SingletonBase _instance = new SingletonBase();
private SingletonBase() {
super(0);
}
public SingletonBase(int i) { // Want to avoid this!
super(i)
}
public static void getInstance() {
return _instance;
}
/* ... */
}
Singleton, of course, cannot have public constructors, so we want to avoid this.
So, what is most elegant way/pattern to have proper Singleton with functionalities from class Base?
Edit: Modifying Base class is prohibited, since it is from an external library.

Constructors are not inherited. So just
delete this part and you'll get what you need.
public SingletonBase(int i) { // Want to avoid this!
super(i)
}
Additionally, you may want to make the Base class
abstract so that no one can instantiate it by mistake
by calling the Base constructor directly.
public abstract class Base {
public Base(int i) {
/* ... */
}
/* ... */
}
public class SingletonBase extends Base {
private static final SingletonBase _instance = new SingletonBase();
private SingletonBase() {
super(0);
}
public static SingletonBase getInstance() {
return _instance;
}
/* ... */
}

You could make SingletonBase just a normal subclass and delegate the Singleton-part to a different class.
I don't know what your specific context is, but you would have Subclass extends Base and somewhere else you would have your SingletonContainer or something like that where you have the method public static Subclass getInstance().
That way, you would have your usual inheritance and also the Singleton effect, since the SingletonContainer would be responsible for keeping only a single instance of Subclass.

It is not because you inherit from a class that have a public constructor that you have to create the same public constructor, you can do :
public class SingletonBase extends Base {
private static final SingletonBase _instance = new SingletonBase();
private SingletonBase() {
super(0);
}
public static void getInstance() {
return _instance;
}
/* ... */
}
Or even :
public class SingletonBase extends Base {
private static final SingletonBase _instance = new SingletonBase();
private SingletonBase() {
super(0);
}
private SingletonBase(int i) { // Want to avoid this!
super(i)
}
public static void getInstance() {
return _instance;
}
/* ... */
}

Related

Accessing overridden method of a private inner class with private constructor

Please find the below snippet :
class Rule
public class Rules {
public static final JarvisFilterRule FILTER = new JarvisFilterRule();
private static class JarvisFilterRule extends RelOptRule {
private JarvisFilterRule() {
super(operand(Filter.class, operand(Query.class, none())));
}
public void onMatch(RelOptRuleCall call) {
// do something
}
}
}
class RelOptRule
public abstract class RelOptRule {
/**
* Description of rule, must be unique within planner. Default is the name
* of the class sans package name, but derived classes are encouraged to
* override.
*/
protected final String description;
public abstract void onMatch(RelOptRuleCall call);
}
My question is : How can I access the onMatch() method of nested class Rules.JarvisFilterRule?
The purpose of the private key word is to prevent access to class members that need to be used exclusively by the class declaring it.
In your case, the Rules class defines JarvisFilterRule to be a private inner class with the intention that its implementation should be known only to the Rules class.
If you wish to access the JarvisFilterRule::onMatch() method inside another class, you will need to replace the private modifier of JarvisFilterRule with public or move the inner class JarvisFilterRule to its own separate file and make it a public class. Like this:
JarvisFilterRule .java
public class JarvisFilterRule extends RelOptRule {
public JarvisFilterRule() {
super(operand(Filter.class, operand(Query.class, none())));
}
public void onMatch(RelOptRuleCall call) {
// do something
}
}
-- OR --
public class Rules {
public static final JarvisFilterRule FILTER = new JarvisFilterRule();
public static class JarvisFilterRule extends RelOptRule {
private JarvisFilterRule() {
super(operand(Filter.class, operand(Query.class, none())));
}
public void onMatch(RelOptRuleCall call) {
// do something
}
}
}
Hope this helps!
Rules.FILTER.onMatch(...)
JarvisFilterRule is not an inner class. An inner class in Java is a nested class that is not static.

How do I create an instance of a inner class in the outer class constructor

I switched from C++ to Java and have a problem with nested classes. I would like to initiate an instance of a subclass in the constructor of the superclass. I tried it like this, but it seems to be wrong.
public class Aircraft {
public class LandingGear {
}
public Aircraft() {
Aircraft.LandingGear myLandingGear = this.new LandingGear();
}
}
The idea is that every instance of the class Aircraft has an instance "myLandingGear" of the subclass LandingGear.
For this use case, your nested class should be static (if it's going to be nested at all), and then you just use a simple new:
public class Aircraft {
public static class LandingGear {
// ----^
}
public Aircraft() {
Aircraft.LandingGear myLandingGear = new LandingGear();
// --------------------------------------^^^^
}
}
When it's not static, it's an inner class, which from your description isn't what you want. More on nested classes in this Java tutorial.
But unless there's a really good reason for LandingGear to be nested inside Aircraft, consider making it a peer instead.
Every Aircraft will have a LandingGear
public class Aircraft {
private LandingGear myLandingGear;
public Aircraft() {
myLandingGear = new LandingGear();
}
public LandingGear getLandingGear() {
return this.myLandingGear;
}
}
public class Aircraft {
public class LandingGear {
public static void m1()
{
//Your code snipet
}
}
public Aircraft() {
LandingGear.m1();
}
}

how java singleton can extends other classes

I am new to java singleton, I want to make my class singleton, so that I have one instance of it in my code.
The class which I want to be singleton is extend another class which its constructor have two entry.
Below code is, what I have done! but it is not correct!
how can I write my singleton
public class Singleton extends Parent{
private Ui ui;
private Store store;
private singleton(Ui ui, Store store) {
super(ui, store);
// TODO Auto-generated constructor stub
}
private static class singletonHolder() {
// My problem is here: how to set value for super class?!
public static final singleton INSTANCE = new singleton();
}
public static singleton getInstance() {
return singletonHolder.INSTANCE;
}
protected Object readResolve() {
return getInstance();
}
public void SetStore(Store dstore){
store = dstore;
}
public void SetUi(Ui uid){
ui = uid;
}
}

Enums and Singletons

Consider the following implementation
public enum Singleton {
INSTANCE;
private final OnlyOne onlyOne;
Singleton() {
onlyOne = new OnlyOne();
}
public static Singleton getInstance() {
return INSTANCE;
}
public static void main(String[] args) {
Singleton one = getInstance();
one.onlyOne.method();
}
}
class OnlyOne {
public void method() {
System.out.println("Hello World");
}
}
Here I have tried to implement the Singleton using enum. I want OnlyOne to have just one instance. My question is how do I restrict clients from instantiating objects of class OnlyOne? Because in some other class we can easily do this
OnlyOne one = new OnlyOne();
I cannot provide a private constructor for it because doing so will break this
Singleton() {
onlyOne = new OnlyOne();
}
Do I need to use the enum as an inner member of OnlyOne class ? Any suggestions?
INSTANCE itself is the singleton. Add your method directly to the enum.
public static void main(String[] args) {
Singleton.INSTANCE.method();
}
public enum Singleton {
INSTANCE;
public void method() {
System.out.println(this);
}
}

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!
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();
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...
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

Categories