Basic concept of value type and reference type.
Any type of variable (whether it is value type or reference type), is pushed on the stack when it is declared.
However, the difference between them is, in case of value types, the value of the object gets stored on stack. Whereas, in case of reference types, the address of the heap gets stored on stack.
So consider the statements:
int a;
DecoratorClass decoratorClass;
Now when these statements run, this is the stack:
STACK:
Variable Value
a 0 // Since ints are assigned to 0 by default
decoratorClass NULL
Now if you try to access the decoratorClass e.g. decoratorClass.memberVariable = xyz;
etc. then you will get a NullPointerException.
This is because, decoratorClass is only declared not initialized. It will get initialized only when you call the constructor.
So when the below statement runs:
decoratorClass = new DecoratorClass();
1) Memory gets allocated on the heap at a particular location(address). The amount of memory allocated in bytes depends upon the class definition (member variables)
HEAP:
xEEEE00
xEEEE01
xEEEE02
xEEEE03
2) Now since some memory is allocated to the object the stack will be updated with the address of the memory
STACK:
Variable Value
a 0 // Since ints are assigned to 0 by default
decoratorClass xEEEE00
Now if you try to access the decoratorClass.memberVariable, you will not get a NullPointer exception because the instance is initialized and memory location is assigned on the stack.
NOW ANSWERS TO YOUR QUESTIONS:
a. What is decoratorClass variable? A reference to the memory location where this variable is created, or something else?
AND
b. In addTest() method I initialize this decoratorClass, what has this become now, a reference to the object, or something else?
Ans:
The decoratorClass variable will be pushed on to stack when the declaration statement is run.
It's values on the stack (which is supposed to be the address on the heap) will be null as memory is not yet allocated on the heap.
Memory will be allocated on the heap when the constructor is called.
The stack will now contain the address on the heap
Let me answer d before I answer c, as I believe it would be simpler for you to understand that way.
d. In testMethod() method I know that a copy of decoratorClass is created and passed, again is it a reference or something else?
Ans:
With the explanation I have given above, in the method testMethod(DecoratorClass d), d is a local variable to testMethod(). But what is the value in d (i.e. value on stack)? It is the address of decoratorClass. So the local variable d points to the same heap and hence the accessing the memberVariable of d will give the same value as accessing the memberVariable of decoratorClass.
Now if you create a new DecoratorClass and assign it to d, it WILL NOT CHANGE decoratorClass. So d might point to EEEE06, but decoratorClass will still point to EEEE00.
Now let's move to c.
c. In case this becomes a reference to the object, then why do we use ref in parameters we want to pass by reference. This question doesn't hold good if decoratorClass is not a reference and something else.
Ans:
Let's consider the same method testMethod(ref DecoratorClass d). Since you are passing d as ref, it is no longer a local variable, but its the same variable.
Now if you create a new DecoratorClass and assign it to d, it WILL CHANGE decoratorClass. So d will point to EEEE06, but will have the effect of decoratorClass also pointing to EEEE06 as both are the same variables on the stack.
For more details on pass object by ref v/s pass object by value check out Memory games
Hope I am elaborate enough.
Cheers!