Understanding reflection's strange behavior
I was writing this piece of code to understand reflection and encountered one scenario where I couldn’t really figure out the reason for the codes’ behavior. Hopefully I receive some guidance from the community.
Following is my test model class & here, for every instantiation, I want to know the exact number of instances created during runtime (using reflection)
public final class Model { private static final Model instance = new Model("Testing"); private static int count = 0; private String name; private Model(String name) { this.name = name; ++count; } public static Model getInstance() { return instance; } public static int getInstanceCount() { return count; } public String getName() { return name; } public void doSomething() { try { System.out.println("Shh.... I am trying to do something"); Thread.sleep(1000); System.out.println("Ok! Done."); return; } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.out.println("Oops! I failed in doing your job..."); } }
The driver code for this scenario is as follows,
public class ReflectionTest { public static void main(String[] args) throws Exception { Model.getInstance().doSomething(); System.out.println(Model.getInstanceCount()); Constructor<?>[] constructor = Model.class.getDeclaredConstructors(); for (Constructor<?> aConstructor : constructor) { aConstructor.setAccessible(true); Model m = (Model) aConstructor.newInstance("Testing through Reflection"); System.out.println(m.getName()); m.doSomething(); System.out.println(m.getInstanceCount()); //System.out.println(Model.getInstanceCount()); } } }
The output for this above piece of code came out to be as follows,
Shh.... I am trying to do something Ok! Done. 0 Testing through Reflection Shh.... I am trying to do something Ok! Done. 1
As you can see, the instance count came out to be 1. I expected it to be as 2.
However, I changed the test model class’s constructor as shown below. The datatype of count is now changed to Integer, instead of previously set ‘int’.
private Model(String name) { this.name = name; if (count == null) count = 0; ++count; }
Surprisingly, I get the correct value for the instance count.
Shh.... I am trying to do something Ok! Done. 1 Testing through Reflection Shh.... I am trying to do something Ok! Done. 2
This might be a silly question, but I am not able to ponder on what really happened behind the scenes. I need some guidance from the community on this.
Thanks in advance.
This has nothing to do with reflection.
private static final Model instance = new Model("Testing"); private static int count = 0;
The initializers are executed in order. So:
private static final Model instance = new Model("Testing");
Executing the constructor causes count
to be incremented from 0 to 1, but then:
private static int count = 0;
Sets count back to zero.
Reverse the order of the declarations.
private static int count = 0; private static final Model instance = new Model("Testing");
Or omit the initializer on count
(its default value is zero anyway).
private static final Model instance = new Model("Testing"); private static int count;