I am trying to write a Singleton Lazy Loading Pattern. Here is the class:
public class IMDBLookup {
private static class LazyLoad {
private static final IMDBLookup IMDB_LOOKUP;
static {
IMDB_LOOKUP = new IMDBLookup();
}
}
public static IMDBLookup getInstance() {
return IMDBLookup.LazyLoad.IMDB_LOOKUP;
}
}
I am wondering whether or not I am doing it in a right way?
Thanks in advance.
I prefer to use enum for simplicity.
public enum IMDBLookup {
INSTANCE;
// add fields and methods here.
}
That is correct. You may want to simplify the inner (holder) class as private static final IMDBLookup IMDB_LOOKUP = new IMDBLookup(); for brevity (to get rid of the static initializer block.)
public class IMDBLookup {
private IMDBLookup(){
// without this I do not get why is it a singleton
// anyone could create instances of your class by the thousands
}
private static class LazyLoad {
private static final IMDBLookup IMDB_LOOKUP;
static {
IMDB_LOOKUP = new IMDBLookup();
}
}
public static IMDBLookup getInstance() {
return IMDBLookup.LazyLoad.IMDB_LOOKUP;
}
}
and you should probably use an enum (not completely sure I do this right)
public class IMDBLookup {
private IMDBLookup(){
}
private static enum LazyLoad {
IMDB_LOOKUP_INSTANCE;
private static final IMDB_LOOKUP = new IMDBLookup();
}
public static IMDBLookup getInstance() {
return LazyLoad.IMDB_LOOKUP_INSTANCE.IMDB_LOOKUP;
}
}
The advice you to think about clone & serialize
import java.io.Serializable;
public class DBConnectionInner implements Cloneable, Serializable {
private static final long serialVersionUID = 1173438078175185035L;
#Override
protected Object clone() throws CloneNotSupportedException {
return new CloneNotSupportedException("CLONE NOT SUPPORT FOR SINGTELTON");
}
protected Object readResolve() {
return getInstance();
}
private DBConnectionInner() {}
static DBConnectionInner getInstance() {
System.out.println("DBConnectionInner getInstance");
return LazyInit.instance;
}
public static class LazyInit {
private static final DBConnectionInner instance = new DBConnectionInner();
}
}
Related
In my Android application I have to initialize a lot of static Objects before the first Activity starts. From what I know, static variables are initialized when classes are loaded. So, with time the amount of static objects in project began to grow and now I'm getting NullPointerExceptions. In my case static objects may call other static objects in their constructors. So my question is: could some static variables be initialized before variables they depend on and thus cause NullPointersExceptions? Is that possible?
Code example :
private static class HardwareManagersHolder implements HardwareManagers, IManagers {
private final AtomicBoolean senderAcquire = new AtomicBoolean(false);
private final AtomicInteger receiverAcquire = new AtomicInteger(0);
public IAudioManager audioManager;
public IVideoManager videoManager;
public IVibrationManager vibrationManager;
public IBatteryHelper batteryHelper;
#Override
public void configureManager() {
audioManager = AudioHelper.getInstance();
vibrationManager = VibrationManager.getInstance();
videoManager = VideoManager.getInstance();
batteryHelper = BatteryHelper.getInstance();
}
And an Object Holder:
public class VideoManager implements IVideoManager {
private static class VideoManagerHolder {
public static final VideoManager VIDEO_MANAGER_INSTANCE = new VideoManager();
}
public static VideoManager getInstance() {
return VideoManagerHolder.VIDEO_MANAGER_INSTANCE;
}
}
I tried to reconstruct your exception with the snippets you provided. I used the following code:
public interface IVideoManager {}
public class VideoManager implements IVideoManager {
private static class HardwareManagersHolder {
public IVideoManager videoManager;
public void configureManager() {
videoManager = VideoManager.getInstance();
}
}
private static class VideoManagerHolder {
public static final VideoManager VIDEO_MANAGER_INSTANCE = new VideoManager();
}
public static VideoManager getInstance() {
return VideoManagerHolder.VIDEO_MANAGER_INSTANCE;
}
public static void main(String[] arg) {
System.out.println("Start test");
HardwareManagersHolder h = new HardwareManagersHolder();
h.configureManager();
if (h.videoManager == null) {
System.out.println("VideoManager is null");
}
System.out.println("Test finished");
}
}
This code works on my machine. If this code is not working on yours, there is some other fault.
Are you initializing them in a static constructor? They would get called first for precisely this reason.
static
{
VIDEO_MANAGER_INSTANCE = new VideoManager();
}
Are both the below approaches for lazy-initializing thread-safe singleton in java correct? Is there any performance difference? If not then why do we use the Holder pattern(Singleton2) instead of keeping it simple as in Singleton1 ?
Thanks in advance.
class Singleton1 {
private Singleton1() {
System.out.println("Singleton1-Constructor");
}
private static final Singleton1 inst1 = new Singleton1();
public static Singleton1 getInst1() {
return inst1;
}
}
class Singleton2 {
private Singleton2() {
System.out.println("Singleton2-Constructor");
}
public static class Holder {
private static final Singleton2 holderInst = new Singleton2();
}
public static Singleton2 getInst2() {
return Holder.holderInst;
}
}
public class App {
public static void main(String[] args) {
Singleton1.getInst1(); // without this statement the Singleton1 constructor doesnt get called.
Singleton2.getInst2(); // without this statement the Singleton2 constructor doesnt get called.
}
}
Singleton1 is not truly lazy, since if you add any other method to Singleton1 and call it from the main class, then the static inst1 will be initialized.
Try this:
public class Singleton1 {
private Singleton1() {
System.out.println("Singleton1-Constructor");
}
private static final Singleton1 inst1 = new Singleton1();
public static Singleton1 getInst1() {
return inst1;
}
public static void foo() {
}
}
public class Singleton2 {
private Singleton2() {
System.out.println("Singleton2-Constructor");
}
public static class Holder {
private static final Singleton2 holderInst = new Singleton2();
}
public static Singleton2 getInst2() {
return Singleton2.Holder.holderInst;
}
public static void bar() {
}
}
public class LazyInitializationApp {
public static void main(String[] args) {
Singleton1.foo();
Singleton2.bar();
}
}
Now running the app will print:
Singleton1-Constructor
But it will not print Singleton2-Constructor, because it is truly lazy.
if i need use a global class what is the best option and why?
public class Global {
public static JSONObject GetJsonResquest(String url){
....
};
}
and then call Global.GetJsonResquest(url) in my activity
OR
public class Singleton {
private static Singleton ourInstance = new Singleton();
public static Singleton getInstance() {
return ourInstance;
}
private Singleton() {
}
public JSONObject GetJsonResquest(String url){
.....
}
}
and then use via Singleton.getInstance().GetJsonResquest("Asd");
When I need a global static variable, I like to group them into a class like
public class MyConstants {
public static final int TIMEOUT = 10000;
}
To use it, i can call it like
long tick = System.currentThreadMillis();
while((System.currentThreadMillis() - tick) < MyConstants.TIMEOUT){
Thread.sleep(1000);
}
So that when I change the TIMEOUT value, I don't have to change other classes that calls it
For global static method, I use them like
public class Utility{
public static boolean isStringValidJson(String jsonString){
return false;
}
}
Same reason as above. When I change isStringValidJson, other classes that calls it don't change
I do use the singleton pattern but only when I override the Application class. However, I set the instance value in OnCreate instead. This means that if OnCreate was not called, getInstance will return null
public class MyApplication extends Application {
private static MyApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static synchronized MyApplication getInstance(){
return instance;
}
}
I'm trying to write a junit test for one of my classes. The design was not done by me; this is a fairly old application, java7, struts1, and clydeDB framework.
The classes are set up like this:
ProcessObj,
IProcessObj (interface),
ProcessHome,
public class ProcessHome {
private static ProcessHome instance = new ProcessHome();
//default Constructor
private ProcessHome() {
}
public static ProcessHome getInstance() {
return instance;
}
public IProcessObj getProcessObj() throws POException {
return ProcessObj.getInstance(); //this is below
}
}
public class ProcessObj implements IProcessObj {
// instance
private static IProcessObj instance;
...
//constuctor
private ProcessObj() throws POException {
init();
}
static IProcessObj getInstance() throws POException {
if (instance == null) {
instance = new ProcessObj();
}
return instance;
}
//jUnit test setUp
#Before
public void setUp() throws Exception {
public static IProcessObj iPO;
iPAO = ProcessHome.getInstance()
.ProcessObj();
Constructor<ProcessObj> pa = ProcessObj.class
.getDeclaredConstructor();
pa.setAccessible(true);
iPO = pa.newInstance();`
...
It works fine up to here, but then in the ProcessObj, the initialization method goes through another set of classes that are set up exactly like the process objects that are above, for the data access layer.
Is there a way that I can create a usable instance of the process object? Can someone explain to me what exactly is going on here? I keep getting a InvocationTargetException.
Why you don't do something like this:
public class ProcessHome {
private static ProcessHome instance = new ProcessHome();
//default Constructor
private ProcessHome() {
}
public static ProcessHome getInstance() {
return instance;
}
public IProcessObj getProcessObj() throws POException {
return ProcessObj.getInstance(); //this is below
}
}
public class ProcessObj implements IProcessObj {
// instance
private static IProcessObj instance;
...
//constuctor
private ProcessObj() throws POException {
init();
}
static IProcessObj getInstance() throws POException {
if (instance == null) {
instance = new ProcessObj();
}
return instance;
}
//jUnit test class
public class ProcessHomeTest {
private IProcessObj iPO = ProcessHome.getInstance()
.ProcessObj();
#Test
public void testIProcessObj() throws Exception {
//use iPO heretest iPO
assertEquals("some","some");
}
I have a class that looks similar to this, and findbugz is complaining about the 'write to the static field from the instance method' (initialize(), and killStaticfield()). I can't set the static field in the ctor.
What is the best fix for this issue?
Would putting staticField in an AtomicReference suffice?
public class Something
{
private static SomeClass staticField = null;
private AnotherClass aClass;
public Something()
{
}
public void initialize()
{
//must be ctor'd in initialize
aClass = new AnotherClass();
staticField = new SomeClass( aClass );
}
public void killStaticField()
{
staticField = null;
}
public static void getStaticField()
{
return staticField;
}
}
Staying as close as possible to your original design...
public class Something {
private static volatile SomeClass staticField = null;
public Something() {
}
public static SomeClass getStaticField() {
if(Something.staticField == null)
Something.staticField = new SomeClass();;
return Something.staticField;
}
}
Refer to your static variable via the class name, that will remove the findbugz warning.
Mark your static variable as volatile, which will make the reference safer in a multithreaded environment.
Even better would be:
public class Something {
private static final SomeClass staticField = new SomeClass();
public Something() {
}
public static SomeClass getStaticField() {
return Something.staticField;
}
}
The question is what you want to do with the static field. If it changes for every class you create it might not be a good idea to have it static at all. If it gets initialized only once you should just lazily initialize it as a singleton.
public class Something
{
private static SomeClass staticField = null;
public Something()
{
}
public static SomeClass getStaticField()
{
if(staticField == null)
staticField = new SomeClass();;
return staticField;
}
}
Remove static from staticField if it should not be static.
Make kill and getStaticField static themselves. And you usually reference static by the class name, not by an (implicit) this, to make very clear that it is static and may cause unexpected consequences in other thReads.
When in doubt, don't use statics for non-constant fields.
The best way is not to do it, try to find a better design patern.
If really necessary this will work and make findbugs/spotbugs not complain.
public class Something
{
private static SomeClass staticField = null;
public Something()
{
}
private void setStaticField(SomeClass value){
staticField=value;
}
public static SomeClass getStaticField()
{
if(staticField == null)
setStaticField(new SomeClass());
return staticField;
}
}