3

I know a little bit about how Java is pass by value, and how passing a object to a method can change the object's field (ex. change1() in the Car class).

However, my question is why change2() and change3() don't change anything (especially change3())

public class question {

    public static void main(String[] args)
    {
        Car c1 = new Car(1000,"Hyundai");
        Car c2 = new Car(2000,"BMW");

        c1.change3(c1);
        c1.change3(c2);

        System.out.println(c1.name  + " "+ c1.price );
        System.out.println(c2.name +  " " + c2.price);
    }
}

class Car
{   
    int price;
    String name;

    Car(int p , String n)
    {
        this.price=p;
        this.name=n;
    }

    void change1(Car c)
    {
        c.price=0;
        c.name="Changed";
    }

    void change2(Car c)
    {
        c = new Car(999,"Honda");
    }

    void change3(Car c)
    {
        c = new Car(888,"Audi");
        c.price=80;
        c.name="xxx";
    }   
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Oscar
  • 47
  • 1
  • 7
  • I have read about pass by refrence and pass by value and how new is to create space from heap ,, but i dont know what is going on still.. – Oscar Feb 08 '20 at 09:05

3 Answers3

2

Every time JVM executes new operator, a new Object/Instance is being created. You are creating a new object of the Car type in your change3(Car c) method and storing the reference on that object into local variable c. After this, anything you set on that c is amending new object, and not the one you passed a reference of.

void change3(Car c) //receives the reference to the object you pass;
{
    c = new Car(888,"Audi"); //creates a new Car object and assigns reference to that **new object** to the variable c.
    c.price=80; //here, you're changing the price/name fields of different object.
    c.name="xxx";
}  

Pay attention, that in change1(Car c) you do not create a new object, but in change2(Car c) and change3(Car c) - you do [explicitly] create new objects.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
  • Thank you for answering my questiion ! but how come the the c2 will be chnaged if i write "c2 = c1.change3(c1);" in main and chanage the chnage3() function to return c instead of void, – Oscar Feb 08 '20 at 09:23
  • 1
    Generally, it's always a good SO standard to upvote the answers which helped you and accept that answers which you think resolved your problem/question. You're welcome. – Giorgi Tsiklauri Feb 08 '20 at 09:28
  • becuas if the local variabel ( c ) will be gone after receving a object from new in a function is true – Oscar Feb 08 '20 at 09:28
  • You are creating a new object in your change2() method. Pay attention.. so whatever you do before will lose the sense, as you're assigning totally new object there. – Giorgi Tsiklauri Feb 08 '20 at 09:30
  • Where do you write `c2=c1.change(c1)`? – Giorgi Tsiklauri Feb 08 '20 at 09:32
  • local variable will be destroyed, but Object will remain alive, and you have reference to that object somewhere else as well. Objects are stored in a different memory location (heap) and local variables are stored in a different memory location (stack). – Giorgi Tsiklauri Feb 08 '20 at 09:33
  • in the main funnction before System.out.println(c1.name + " "+ c1.price ); – Oscar Feb 08 '20 at 09:35
  • I guess i made my self more confusing now , but your answer is clear for my first question, thanks a lot ! – Oscar Feb 08 '20 at 09:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/207451/discussion-between-giorgi-tsiklauri-and-oscar). – Giorgi Tsiklauri Feb 08 '20 at 09:40
0

Edited: Java is pass by value for primitives and for objects, it's a copy of the original reference.

To be more specific it's a copy of the same reference, which means that is a different pointer to the same reference of the same object, so if you change the object in your method, the original object is going to change too. BUT if you assign it again (with the new operator in your case) , you are going to update your pointer inside your method to a new reference, but the original pointer remains as it was.

Eduardo Pérez
  • 488
  • 3
  • 10
  • 2
    Wrong. Java is always pass by value. – Giorgi Tsiklauri Feb 08 '20 at 09:11
  • It's specified in the second paragraph is a "value of the reference" – Eduardo Pérez Feb 08 '20 at 09:17
  • @EduardoPérez, but the first sentence (what most people will read) is misleading. – lealceldeiro Feb 08 '20 at 09:18
  • _"so if you change the object in your method, the original object is going to change too"_, this is not so either... the only exceptions with this are "collections" which are pointers to the object references such as `List`, `Array`s, etc. – lealceldeiro Feb 08 '20 at 09:20
  • 2
    Sorry, man, but your answer is super ambiguous and will lead the learner into much more confusion. First it says that it has `pass by reference`. .then it says that `that is a different reference to the same object` - which is also wrong. Address value which constitutes reference will be copied and that's what again proves that Java is Always pass by value. – Giorgi Tsiklauri Feb 08 '20 at 09:20
  • You are right Giorgi, I hope the new changes make more sense – Eduardo Pérez Feb 08 '20 at 09:25
0

Another about probably most upvoted question about Java on StackOverflow :)

The pass by value or reference probably comes from the understanding and conventions used in C++ language.

The types of parameters are passed by value.
But when passing an object it doesn't pass the whole object, but a copy of address in memory (aka reference) pointing to that object.
Passing parameter by reference means it's possible to change that parameter inside of an method and that change would be visible outside of that method.
Java in "passed by value" because changing/reassigning the passed parameter isn't visible outside of an method.

In the case of:

void change1(Car c)
{
    c.price=0;
    c.name="Changed";
}

The assignments to price and name are visible outside of that method, because the the method changes the member fields of the passed instance and not the instance itself.

The change2 and change3 methods doesn't reflect outside of them because of reassigning the passed c parameter.
When reassigning passed object, the address behind passed object parameter no longer points to the same object as originally passed one.
Similary, it's not possible to reflect the change or reassigning of passed primitive or:

void change4(String name) {
    name = "whoopsie";
}
//and later calling it with:
c1.change4(c1.name);

Changing the inner state of an object isn't the same as changing the object itself.

itwasntme
  • 1,442
  • 4
  • 21
  • 28