Given:
public class Example {
static String staticField = "staticField";
String instanceField = "instanceField";
public void foo() {
String local = "local";
}
}
staticField
The string itself is on the heap, like all strings are. The static field named staticField
is a reference that points at this. There's only one such reference (there is one place in memory of (usually*) 4 to 8 bytes pointing at it. This 'place in memory' is a bit tricky as to where it lives; generally on the heap, same place class files live.
instanceField
This is much simpler to answer. There is no such field, at all, until someone makes a new object. And objects are.. on the heap. Imagine some entirely different code:
public void foo() {
Example e = new Example();
}
This makes a new Example object and in so doing, we now have one instance of instanceField
. The Example object is created on the heap, it occupies some memory. Part of that memory involves that 4 to 8 byte long reference (pointer) to the "instanceField"
string, which also lives on the heap, probably in an entirely different spot. Then, the local field e
, which lives on stack, will reference (point at) that.
So, we have e
(living on stack), containing a memory address in the heap where an instance of Example
lives, and within the memory used by that, there is a memory address that points at a different place on the heap where the string "instanceField"
is located.
local
Finally, there's local
, which is 4 to 8 bytes on the stack, pointing at a string living on the heap.
*) Any JVM is free to implement this however they want.