I have this two codes:
A a = new A();
B b = a.getB();
B b = new A().getB();
In the first code I created two objects and saved them so the program need memory for two objects
but in the second code I created object from A and I didn't saved it in any variable so my question is :
what is the different between this two codes? is it just a syntax or there is an effect on memory?
For light objects, very few differences.
In the first code the A object is assigned to a variable. So it is eligible to be garbage collected only as the variable is out of the scope.
In the second code the A object is not assigned to a variable. So it is right now eligible to be garbage collected.
In a general way you should not worry about this kind of things and using a variable or not using it only if it makes sense.
Reference/Pointer versus Object
Your term "saved" has no technical meaning, and may be confusing you.
Let’s get more concrete. Replace
A
class withCat
class. ReplaceB
class withBreed
class.Let's assume that when instantiating a
Cat
we also instantiate aBreed
object held within thatCat
object. In other words, we are not doing lazy-loading in this example. So when instantiating aCat
, we pass along an instance ofBreed
to the constructor.Two lines
The
Cat a
variable does not hold aCat
object, it holds a reference (a pointer) to theCat
object that was constructed elsewhere in memory. That location of theCat
object in memory, basically a number, is what is held by theCat a
.You can think of that line of code as this:
Conceptual diagram:
Notice that the only way to access the
Breed
object is to go through theCat
objectFluffy
. The only way our code can get to thatCat
object is through the reference/pointer variable nameda
.After that code we have wee bit of memory now allocated to holding another pointer/reference, the variable named
b
. Theb
variable is notCat
nor aBreed
, it is the memory location of where to find theBreed
object elsewhere in memory. We can now directly access theBreed
object, without going through theCat
instance.Conceptual diagram:
One line
Your other code:
…converted to our example:
…is quite similar, but never establishes the reference
a
as a named variable. The reference is generated, at least conceptually (in actuality a JVM may have optimizations). The brief ephemeral reference is used to immediately call thegetBreed
method.After obtaining a memory-location of the
Breed
object, the ephemeral reference to the newCat
object is released, and the newCat
object falls out of scope. The newCat
object technically is likely still floating in memory for a moment, becoming a candidate for garbage-collection, due to be purged from memory.Of course the new one-liner seen above using
Cat
andBreed
becomes silly: We instantiate a newBreed
, pass it to the constructor ofCat
, and then immediately ask to get it back. Let’s ignore the awkward silliness for the sake of this memory-management discussion.Conceptual diagram:
As for memory management, the same amount of memory is likely taken in both your scenarios (depending on your JVM implementation). Both scenarios are establishing a pair of objects and a pair of references. The one slight difference is that in your second scenario the
Cat
object and its ephemeral pointer go out of scope immediately, and become candidates for garbage-collection. So memory might be reclaimed sooner than in your first scenario. In practice, the difference would likely be insignificant.Do not micro-optimize
As others commented, all this is merely academic. You generally should not worry about such micro-optimizations.
The modern compilers and JVMs are extremely well-optimized, some of the most well-optimized and well-tested large software projects ever. So the best way to write Java code is simply. Write simple easy-to-read and easy-to-understand code for humans, and you will also be writing code that is most likely to be well-optimized by the compiler and JVM. Trying to be clever by out-thinking the compiler & JVM is ironically liable to be counter-productive, resulting is less-optimized code.
You kinda answered your own question. In the first example, you created two variables 'A' and 'B' so more memory is used. In the second example, you only created on variable B, so less memory is used. In the second example, a new 'A' is created then the newly object calls the method getB() and the result is stored in the variable 'B'. In this situation the memory difference is very minimal, but if this was repeated multiple times over the course of a program then the memory usage could stack up.
Also, Java has its own garbage collector and when it runs it collects/deleted the memory of the objects that are no longer accessible. Once a variable goes out of scope, then the garbage collection can run and clean up that unused memory. With the garage collector in place, the memory difference in the two statements almost does not matter.