Java对象内存分配理解存疑,请求答疑(附代码示例)
Hey there! Let's work through your Java object memory allocation confusion step by step, using your code as a starting point. First, let's fix up the syntax errors in your sample code to make it compile properly—this will help us talk about memory behavior clearly:
class A { int a; B b; public B getB() { return this.b; } public void setB(B b) { this.b = b; } } class B { Float amount; String type; B(Float amount, String type) { this.amount = amount; this.type = type; } // Fixed return type here—should be String, not B public String getType() { return this.type; } public void setType(String type) { this.type = type; } // Assuming you meant an override of toString() for debugging @Override public String toString() { return "B{amount=" + amount + ", type='" + type + "'}"; } }
Now let's break down how memory is allocated when you use these classes—this is likely where your original understanding was off:
Stack vs. Heap Basics:
- Primitive types (like
int ain class A) and object references (likeB bin class A) live on the stack when they're local variables. But when they're member variables of a class, they're stored as part of the object's data on the heap. - Actual objects (instances of
AandB) are always allocated on the heap—never the stack.
- Primitive types (like
When you create a
Binstance:B bInstance = new B(10.5f, "test");- The
new B(...)call carves out space on the heap for theBobject: this includes slots for theFloat amountreference andString typereference. - The
bInstancevariable (a reference that points to the heap object) lives on the stack if it's a local variable, or as part of another object on the heap if it's a member variable. - The
Floatwrapping10.5fand theString "test"are separate heap objects too—yourBinstance just holds references to them, not the actual values.
- The
When you link an
Ainstance to aBinstance:A aInstance = new A(); aInstance.setB(bInstance);new A()allocates heap space for theAobject: this includes the primitiveint a(which defaults to 0) and theB breference (which defaults tonulluntil you callsetB).- When you run
setB(bInstance), you're copying the reference value ofbInstanceinto thebmember ofaInstance. Now bothbInstance(stack) andaInstance.b(heap, part of theAobject) point to the exact sameBobject on the heap.
Key Reference Behavior to Note:
If you later do this:B anotherB = new B(20.0f, "newTest"); aInstance.setB(anotherB);You're not modifying the original
Bobject thatbInstancepoints to—you're just updating the reference stored inaInstance.bto point to the newBobject. The originalBobject will be eligible for garbage collection if no other references point to it.Common Misconception Bust:
Java is always pass-by-value. When you pass an object to a method (likesetB(B b)), you're passing the value of the reference, not the object itself. So modifying the parameterbinside the method (e.g.,b = new B(...)) won't change the original reference outside—but modifying the object's members (e.g.,b.setType("updated")) will affect the actual heap object, since both references point to the same thing.
If you had a specific unexpected behavior in your code that threw you off, feel free to share those details, and we can dig even deeper!
内容的提问来源于stack exchange,提问作者Ashish

