Suppose I have several classes that are "weak singletons" - things that shouldn't be initialized more than once (registering listeners, etc.), but for whatever reason I can't make them real singletons or even static classes, so the best I can do is warn myself (or throw a RuntimeException
I guess, but for this question's purposes it doesn't matter how I handle it).
public class WidgetManager {
private static boolean initialized = false;
// stuff to be initialized only once
public WidgetManager() {
if (initialized) Main.LOGGER.warn("Instantiating multiple instances of " + getClass().getName() + "!");
// initialize stuff
initialized = true;
}
}
There are several of these "weak singletons", so typing them by hand gets tiring. Plus it also feels like there should be a better way to do my checks, so as not to repeat myself.
public class FooWidget {
private static boolean initialized = false;
// stuff
public FooWidget() {
if (initialized) // ...
// ...
}
}
public class BarWidget {
// this gets tiring
}
Private functions in interfaces don't work - private
makes the functions in it only available within the interface definition.
public interface WeakSingleton {
private void warnReinitialization(boolean initialized) {
if (initialized) Main.LOGGER.warn("...");
}
}
public class WidgetManager implements WeakSingleton {
private static boolean initialized = false;
public WidgetManager() {
warnReinitialization(initialized); // <-- Error, function not visible
initialized = true;
}
}
default
works, but it exposes it everywhere.
public interface WeakSingleton {
default void warnReinitialization(boolean initialized) {
// ...
}
}
public class WidgetManager implements WeakSingleton {
private static boolean initialized = false;
public WidgetManager() {
warnReinitialization(initialized); // <-- Works here
initialized = true;
}
}
public class Main {
public static void main(String[] args) {
new WidgetManager().warnReinitialization(); // <-- Oops, the interface "leaked" ...
}
}
On the surface an abstract class saved me defining the boolean and checking it:
public abstract class WeakSingleton {
protected static boolean initialized = false;
protected void warnReinitialization() {
if (initialized) System.out.println("Warning: Reinitializing " + getClass().getName() + "!");
}
}
public class WidgetManager extends WeakSingleton {
private FooWidget foo;
private BarWidget bar;
public WidgetManager() {
warnReinitialization();
System.out.println("WidgetManager ctor");
initialized = true;
}
}
public class FooWidget extends WeakSingleton {
public FooWidget() {
warnReinitialization();
System.out.println("FooWidget ctor");
initialized = true;
}
}
public class BarWidget extends WeakSingleton {
public BarWidget() {
warnReinitialization();
System.out.println("BarWidget ctor");
foo = new FooWidget();
bar = new BarWidget();
initialized = true;
}
}
public class Main {
public static void main(String[] args) {
new WidgetManager();
}
}
Unfortunately it breaks in other ways:
user@host:~ $ javac *
user@host:~ $ java Main
WidgetManager ctor
FooWidget ctor
Warning: Reinitializing BarWidget!
BarWidget ctor
user@host:~ $
Questionable design aside, is there a way to achieve my goals of reducing the amount of typing I need for my check without leaking the checking function?
Thank you for your time.
You can make the constructor private
, the class final
and create exactly one instance:
public final class WidgetManager {
public static final WidgetManager INSTANCE = new WidgetManager();
private WidgetManager() {
}
}
But I don't think you need to have singletons for listeners, just create a new instance each time, even if nothing about the instances is different.