0

I am getting a bit confused regarding few points regarding Java memory management.

Understood what is the difference between Stacks and Heap and I went to see a proper example on what is those memories when we execute some code.

I took for example this few lines

public static void main(String[] args)
{
    int a = 5;
    calculate(a);
    System.out.println(a); //will print 5 not 50
}
private static void calculatee(int a)
{
    a = a * 10;
}

I understood what is happening in the stack and in the heap. The variable is not getting returned and there is no reference to the Heap in this case.

while in this example:

public static void maina(String[] args)
{
    Customer customer = new Customer("John");
    setAName(customer);
    System.out.println(customer.getName()); // this will return Philip
}

private static void setAName(Customer c)
{
    c.setName("Philip");
}

I can see the state of the object changed this time!

Stacks are not shared thought threads, but heap is shared! Which make sense to me that the object customer has changed its value from Jhon to Philip when I am printing it! Great! all make sense!

However, I was expecting that if I will do this

public static void main(String[] args)
{
    Integer i = new Integer(5);
    calculate(i);
    System.out.println(i); // printing 5 and not 50
}
private static void calculate(Integer i)
{
    i = i * 10;
}

I would get 50 and not 5!

In this case Integer is an object and I am assuming it is created in the heap!

Funny thing is that if I will wrap the Integer inside Customer I will get 50 instead of 5.

Why is this happening? Isn't the Integer type getting created in the Heap?

OEH
  • 665
  • 11
  • 29
  • 2
    Related: https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value (Nothing to do with heaps and stacks, your terminology is confused.) – Michael Berry Dec 04 '18 at 15:58

1 Answers1

1

This is a problem of references and not of heaps and stacks.

When calling the method calculate, you pass a reference (in your case, i from main).

The trick is, that Java will create a new reference inside of calculate. So i inside of calculate and i inside of main might initially "point" to the same object, but they are not the "same".

So, if you change i inside of calculate to the object resulting from your multiplication, you don't automatically change the reference of the i inside of main.

With Customer, it's different. You never change where c in setAName points to. You change one reference inside of the object, but both customer inside of main and c in setAName still point to that one object!

Here two shitty Paint drawings to explain what I mean (numbers prefixed with 0x are references):

For the Integer example:

Integer Graph

For the Customer example:

Customer Graph

Don't hesitate to come back with any questions.

I hope this helps.

Markus Appel
  • 3,138
  • 1
  • 17
  • 46
  • got it... If i will try to do a "c = new Cusotmer (...)" inside of setAName() I will actually no change on the customer value... That happens cause name is a member variable. thank you very much – OEH Dec 04 '18 at 16:17
  • 1
    @OEH good idea! Welcome to the world of immutability, where a reference, once set, will never be changed again. (Instead, any transformation will result in a "new" object). This allows you to think more simply about your code, as you never have to remember where an object might be changed - it won't. In Java, this can be enforced by using `final`. – Markus Appel Dec 04 '18 at 16:24