Initializing static final variable in declaration vs initializing during Application.OnCreate() - java

I want to store an object state between activities (already considered Parcelables, JSON, yadda yadda) but since I have a couple of Singletons, might as well refer to them in a class that extend Application (modularity + easy to maintain).
So to my question, let's say I have a simple singleton:
class SimpleSingleton
{
private static final SimpleSingleton instance; //The question will refer this line later.
public static SimpleSingleton getInstance()
{
return instance;
}
private SimpleSingleton(){}
}
1: At first I create an initInstance() method within the above class, e.g:
class SimpleSingleton
{
//... the code above
public static void initInstance()
{
if(instance == null) instance = new SimpleSingleton();
}
}
2: Hence the below works, (in which afterwards, I can refer to the singleton from any activity via CustomSingleton.getInstance()):
class MyApp extends Application
{
#Override
public void onCreate()
{
super.onCreate();
initSingletons();
}
protected void initSingletons()
{
SimpleSingleton.initInstance();
}
}
BUT. What if I declare
private static final SimpleSingleton instance = new SimpleSingleton();
instead of
private static final SimpleSingleton instance;
in the SimpleSingleton class?
I assume the object is initialized during compile time, so doesn't that makes the whole #1 and #2 unnecessary? Or do I get the order wrong (especially WHEN the class is actually initialized)? I came from C# and currently developing for Android so this kinda gave me a quick gotcha when I want to refer to my Singletons. Also, I ask this since according to this blog:
The explanation of the weird behavior I saw that makes more sense to me is that the static variables instances are bound to the class loader of the class that first initialized them.

The only difference i can think of is when you do
private static final CustomObject instance = new CustomObject();
when you application is launched it will create and allocate space for it.
Note it might never be used but it would still be using memory.
when you create it on an onCreate method it will only create an instance when it is called.
Using static also has one more disadvantage that is it will use your perm gen space and if by chance it fails to give it space or fails to create it your program will crash on startup. Leaving you confused.
I strongly suggest using the onCreate method approach.

Related

Constructor newInstance generates local instance only

Looks I miss something in my tests (Robolectrics|Powermockito).
I have following class with Singleton:
public class Core{
private static Core instance = new Core();
public static Core getInstance() {
return instance;
}
public static void destroy(){
instance = null;
}
}
In my tests I kill the instance with Core.destroy()
and therefore Core.getInstance() returns null.
So every test I want to re-generate instance again. I do the following:
Constructor<Core> constructor = Core.class.getDeclaredConstructor();
constructor.setAccessible(true);
Core newCore = constructor.newInstance();
So now newCore is initialized but Core.getInstance() still returns null.
How to initialize properly Core -> instance?
There is an important point that I often try to explain to people when talking about singletons:
There's a difference between a singleton and something that you will only create 1 instance of. And, often, when you think you want a singleton, actually you just want something that you will only create 1 instance of.
The difference between these two things is perhaps not apparent at first, but important to realize, especially when you find yourself in a position where you need to purge the internal state of a singleton between tests.
If you have a singleton - a true singleton - there is, by definition, one instance that can exist in the JVM. If this has mutable state, this is problematic, because it means that you have to care about that state. In tests, you have to clear state between runs to remove any effects owing to the ordering of test execution; and you have to run your tests serially.
If you use dependency injection (as in the concept, not any particular framework like Guice, Dagger, Spring etc), it doesn't matter to classes using the instance where that instance came from: you, as a client of the class, get control over its life cycle. So, whereas your production code uses the same instance in all places, your testing code can use separate instances - thus they are decoupled - and often you don't even have to worry about cleaning up state at all, because your next test case can simply create a new instance of the class.
So, instead of code using your Core class like so:
class MyClass {
void foo() {
Core core = Core.getInstance();
// ... do stuff with the Core instance.
}
}
you can write it instead like:
class MyClass {
private final Core core;
MyClass(Core core) { this.core = core; }
void foo() {
// ... do stuff with the Core instance.
}
}
and you have broken the static binding between MyClass and Core. You can instantiate MyClass in tests with separate instances of Core:
MyClass myClass = new MyClass(new Core());
// Assert something...
or, if multiple instances need to interact with the same instance of Core:
Core core = new Core();
MyClass myClass = new MyClass(core);
MyOtherClass myOtherClass = new MyOtherClass(core);
// Assert something...
You should make the constructor private so that code using you singleton class cannot create an instance using it and they should only get an instance using the getInstance() method.
Also the lifetime of a singleton object is typically tied to the JVM, as there should be a single instance of a singleton class per JVM. So if you can destroy and re-create the instance it is not a true Singleton IMO, so I assume you only want to re-create the instance for testing.
To re-create the singleton from your test classes after calling the destroy() method you can get the Field of the class having the instance of your class. Using that Field you can set it to the new instance you created:
public static void main(String[] args) throws Exception {
System.out.println(Core.getInstance()); //gets instance
Core.destroy();
System.out.println(Core.getInstance()); // null
reinitializeInstance(Core.class);
System.out.println(Core.getInstance()); //gets instance
}
public static void reinitializeInstance(Class<Core> clazz) {
try {
Constructor<Core> constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
Core newCore = constructor.newInstance();
Field field = Core.class.getDeclaredField("instance"); //gets the instance field
field.setAccessible(true);
field.set(newCore, newCore);
} catch (Exception e) {
e.printStackTrace();
}
}
And your Singleton class:
class Core {
private static Core instance = new Core();
// To prevent reflection from creating a new instance without destroying the first one
private Core() {
if(instance != null){
throw new IllegalStateException("Instance already exists!");
}
}
public static Core getInstance() {
return instance;
}
public static void destroy() {
instance = null;
}
}
public class Core {
private static class SingletonHolder {
private static AtomicReference<Core> instance = new AtomicReference(new Core());
}
public static Core getInstance() {
return SingletonHolder.instance.get();
}
public static void destroy() {
SingletonHolder.instance.set(null);
}
public static void reset() {
SingletonHolder.instance.compareAndSet(null, new Core());
}
}
Using an extra "superfluous" inner class is done for concurrent initialisation, ensuring that the static field is initialized once.
Changing the instance (destroy, my reset) needs some kind of synchronisation for objects.
Instead of the more costly synchronize one can use an AtomicReference.
compareAndSet does not set the instance with a new value, if there is already an old value.
It is also worth having
Optional<Core> getInstance() { ... }
So the usage is safe-guarded.
Core.getInstance().ifPresent(core -> { ... core ... });
First of all you're making Core constructor accessible, but it's public by default already.
Second, when your calling the constructor, it just creates a new instance of Core, which does nothing to instance, because constructor, created by default is empty and because constructor is not the place to initialize Singleton.
If you want to refresh singleton instance you should have a dedicated method for that.
How about this pattern instead?
public class Core{
private static Core instance;
public static Core getInstance() {
if(instance == null) instance = new Core();
return instance;
}
public static void destroy(){
instance = null;
}
}
And if you only want to destory in tests, you can remove "public" from your destroy() method

Java static instance

So I just started my fist big project in Java and I'm following some tutorial but there is code that I dont understand at all.
package com.Legolando.Runa;
import net.minecraftforge.fml.common.Mod;
#Mod(modid = Reference.MODID, name = Reference.MODNAME, version = Reference.VERSION)
public class Runa {
#Mod.Instance
public static Runa instance = new Runa();
// I dont get why instance of my class has to be static
}
As you see I create an instance of this class inside this class (already cosmos for me) and this instance is static. Can someone explain what is a static instance? Is it the same as static variable or method?
This code reminds me of Singleton Class in java.
public class Runa {
private static Runa singleton = new Runa( );
/* A private Constructor prevents any other
* class from instantiating.
*/
private Runa() { }
/* Static 'instance' method */
public static Runa getInstance( ) {
return singleton;
}
/* Other methods protected by singleton-ness */
protected static void demoMethod( ) {
System.out.println("demoMethod for singleton");
}
}
FYI, Singleton ensures that only one object of created for class Runa inside the application. Try to google a bit for more understanding of Singleton usage in java
Links:
https://www.tutorialspoint.com/java/java_using_singleton.htm
Best of Luck
This most probably refers to a design pattern in software development, called a singleton.
I.e. the class is designed to feature only a single instance, accessible through static means. This isn't a good example of a singleton however, as every field should only be accesses through methods. Furthermore, a private constructor might be required to prevent other classes from instantiating the singleton.

Is this the wrong way of initializing Singleton classes in Java? [duplicate]

This question already has answers here:
What is an efficient way to implement a singleton pattern in Java? [closed]
(29 answers)
Closed 6 years ago.
I had my singleton class initially like this
private static MqttHandler instance = new MqttHandler();
private MqttHandler(){};
public MqttHandler getInstance(){
return instance;
}
Now in one phone it was working as expected, but in another, seems like it was creating many instances, since whenever I tried to log something, it did log multiple times. I have no idea why.
The second time I tried using this
private MqttHandler instance;
private MqttHandler(){};
public MqttHandler getInstance(){
if(instance==null) instance == new MqttHandler();
return instance;
}
Seems to be working, at least for now, not sure if its going to crash later, Does this mean that, in my first method, whenever I returned instance, it was calling
new MqttHandler();
thus creating new instances all the time? Why would it work on one device correctly, and then refuse completely on a different one?
This is how to implement a simple singleton:
// It must be static and final to prevent later modification
private static final MqttHandler INSTANCE = new MqttHandler();
// The constructor must be private to prevent external instantiation
private MqttHandler(){};
// The public static method allowing to get the instance
public static MqttHandler getInstance() {
return INSTANCE;
}
Your second approach will work only on single threaded application because if you call getInstance at the same time with several concurrent threads, it will create several instances of your object such that the contract of your singleton would be broken. So if you need to properly lazy create your singleton, here is how to proceed:
// The constructor must be private to prevent external instantiation
private MqttHandler(){};
// The public static method allowing to get the instance
public static MqttHandler getInstance() {
return MqttHandlerHolder.INSTANCE;
}
/**
* The static inner class responsible for creating your instance only on demand,
* because the static fields of a class are only initialized when the class
* is explicitly called, this rule is also applicable to inner static class
* So here INSTANCE will be created only when MqttHandlerHolder.INSTANCE will be called
*/
private static class MqttHandlerHolder {
private static final MqttHandler INSTANCE = new MqttHandler();
}
Both should have the same effect. Of course the latter has the benefit that the object isn't created until actually needed, but be aware that the object could be created multiple times due to concurrent calls to getInstance.
Also, you need a "static" declaration in getInstance (otherwise you would have to create an instance to get the singleton).

How to Return an Object Via Static Factory Methods?

I know Java basics, and now I'm in the journey of reading Effective Java. The book suggest using static factory methods instead of constructors. So I have Groovy code like this:
public class Anto {
public static void main(String[] args) {
println Java.javaInstance()
}
}
class Java {
public static Java javaInstance() {
return this
}
}
When I compile this, I get an error like this:
Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class Java' with class 'java.lang.Class' to class 'Java'
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class Java' with class 'java.lang.Class' to class 'Java'
at Java.javaInstance(Anto.groovy:9)
at Java$javaInstance.call(Unknown Source)
at Anto.main(Anto.groovy:3)
Where am I making a mistake?
You can do it using return new Java();. Static methods don't have access to this.
EDIT:
These static factories are usually singletons, which means that only one instance of the class should be used (typically, a connection to a db for example). If you want do add this dimension to your Java class, use a private static attribute as follow:
class Java {
private static Java instance;
public static Java javaInstance() {
if(instance == null) {
instance = new Java();
}
return instance;
}
}
Creating a Singleton correctly can be easy to get wrong (especially in a multi-threaded environment), so you're probably better using the Singleton annotation that comes with Groovy rather than rolling your own:
public class Anto {
public static void main(String[] args) {
println Java.instance
}
}
#Singleton
class Java {
}
This transforms the Java class to:
class Java {
private static volatile Java instance
private Java() {}
static Java getInstance () {
if( instance ) {
instance
} else {
synchronized( Java ) {
if( instance ) {
instance
} else {
instance = new Java()
}
}
}
}
}
A good (albeit not specific to Groovy) example of a library that uses static factory methods that you could look at would be Google Guava. Guava uses this idiom in a number of places. For example, their Range class supports nine types of ranges, and if they used normal constructors, their signatures would conflict in several cases since the only thing you can use to distinguish them is their arguments.
Static methods on the other hand can also be distinguished by their name, so Guava defines different ones for each type of Range. Internally these methods still call a normal constructor, but it's not one that's publicly accessible.
import com.google.common.collect.Ranges
import com.google.common.collect.DiscreteDomains
final dom = DiscreteDomains.integers()
assert [1,2,3,4,5] as Set == Ranges.closed(1, 5).asSet(dom)
assert [2,3,4] as Set == Ranges.open(1, 5).asSet(dom)
This is a useful idiom, but not one that should just be automatically preferred over a normal constructor. In situations where a normal constructor would have sufficed, you've at best written more code than you needed and at worst have made extending the class impossible, since any subclasses will still need a public or protected constructor they can call.
You can't use this because static methods are not instance methods.
Each time you create a new instance of a particular class, that new object/instance as it's own state. this points to a particular instance.
Are you trying to make a singleton ? Meaning you just want a single instance of a class ?
class Singleton {
//static reference to a particular instance
private static Singleton instance;
//private constructor so that it cant be called outside this class scope
private Singleton();
//synchronized in case your working in threaded enviroment
public synchronized static Singleton getInstance()
{
if(NULL == instance)
{
instance = new Singleton();
}
return instance;
}
}

Need help to get two classes to assist each other

i'm currently just fooling around with different classes to test how they work together, but im getting an error message in NetBeans that i cant solve. Here's my code:
class first_class.java
public class first_class {
private second_class state;
int test_tal=2;
public void test (int n) {
if (n>2) {
System.out.println("HELLO");
}
else {
System.out.println("GOODBYE");
}
}
public static void main(String[] args) {
state.john();
TestingFunStuff.test(2);
}
}
class second_class
public class second_class {
first_class state;
public int john () {
if (state.test_tal==2) {
return 4;
}
else {
return 5;
}
}
}
Apparently i can't run the method "john" in my main class, because "non static variable state cannot be referenced from a static context" and the method "test" because "non static method test(int) cannot be referenced from a static context".
What does this mean exactly?
Screenshot of the error shown in netbeans: http://imageshack.us/photo/my-images/26/funstufffirstclassnetbe.png/
It means state must be declared as a static member if you're going to use it from a static method, or you need an instance of first_class from which you can access a non-static member. In the latter case, you'll need to provide a getter method (or make it public, but ew).
Also, you don't instantiate an instance of second_class, so after it compiles, you'll get a NullPointerException: static or not, there needs to be an instance to access an instance method.
I might recommend following Java naming conventions, use camelCase instead of under_scores, and start class names with upper-case letters.
The trick here to get rid of the error message is to move the heavy work outside of main. Let's assume that both lines are part of a setup routine.
state.john();
TestingFunStuff.test(2);
We could create a function called setup which contains the two lines.
public void setup() {
state.john();
TestingFunStuff.test(2);
}
Now the main routine can call setup instead, and the error is gone.
public static void main(String[] args) {
setup();
}
However, the other members are correct in that your instantiation needs some cleanup as well. If you are new to objects and getting them to work together might I recommend the Head First Java book. Good first read (note first not reference) and not all that expensive.
Classes can have two types of members by initialization: static and dynamic (default). This controls the time the member is allocated.
Static is allocated at class declaration time, so is always available, cannot be inherited/overridden, etc. Dynamic is allocated at class instantiation time, so you have to new your class if you want to access such members...
It is like BSS vs heap (malloc'd) memory in C, if that helps..

Categories

Resources