0

I'm Ryan who's a rookie in programming. I was going through the OOP part of my textbook today and I found a part that I won't understand at all. There are 2 codes, I'll have them copied here. The first one is :

public class Change {

    public static void main(String[] args) {
             int x = 17;                                 
               dontChange(x);                          
               System.out.println(x);
    }
    static void dontChange(int z) {                
        z = 42;                                 
    }                                       
}

When the code was executed. The output would still be 17, which is not the expected 42(in my understanding of parameter and Method.)

The textbook provided another example as well, which results in a change.

public class Change {   

void change(Student s) {//student is a type

    s.name = "Fred";

public static void main(String[] args) {  
    
     stu.name = "Jane";
     change(stu);

     System.out.println(stu.name);
 }
}                  

This code would result in the output the name as 'Fred', I was wondering where's the difference between them and what was the reason behind these codes when they look similar and worked totally differently.

Thank you for going through the whole post, I wish you have a great day!

Ryanzz
  • 19
  • 5
  • Hi Knittl, I think that's a bit confusing to me, I don't get his/her code. But I got the idea of pass by value and pass by reference. – Ryanzz May 22 '22 at 21:12
  • pass-by-value says exactly this: a value passed to a method cannot be changed. If the value is a complex object, then any properties of the object can be changed (but the object itself cannot be swapped for a different object) – knittl May 22 '22 at 21:30
  • Thank you very much Knittl For the explanation! I really appreciate it! – Ryanzz May 23 '22 at 00:07

4 Answers4

0

You need to distinguish between “passing by value” and “passing by reference”. Maybe this helps

Jelmen
  • 173
  • 9
0

If you want to understand the answer to this Question, why the value does not change, you have to understand, why the value sometimes change.

The values changes,if the Datatyp is referencial. This means, that the data is stored at the heap(a part of memory) and our variable only points to this data. This means, that your variable only stores, where the data is really stored.

If we change our data,we are following our reference and change it there. This means, that every reference, which points at our data is also changed. It is the same object.

What happens here is different. You are not dealing with referencial Datatyps. You are dealing with primitives(int, float, char....). Those datatyps aren't stored in the heap. They are stored in the stack(another part of memory). This means, that the data is really stored in our variable. So, if we change our data in our variable, we aren't following an reference and change it there. We are really changing the value in our variable.

An analogy: Referencial types are like notes, which point to a different note. In the second note is the data. If we try to change the datanote, we take a look at our first note with the reference to the datanote and then change the datanote. Any note pointing to the datanote has now the updated data.

primitives are like, if our first note has all the data. There is no pointing to somewhere else. It is our data

Primitives start most of the time with a lower case letter. Primitives can't have any functions or anything. Refercal start most of the time with a Capital letter. They can have functions and are most of the time classes

What you wanted to do was to return the new value and set it equal to x.

I hope, i've helped you a bit. If you have any Questions left, feel free to ask sorry for my English:)

Max
  • 61
  • 3
  • Hi Max! Thank you very much for the long explanation and things are making so freaking much more sense now. I like the way you made the analogy with notebook and data notes! That was the candy! And the heap thing, I actually was confused with it when I was on my own reading the textbook, and you explained it well! Thanks a lot! Hope you have a great one! – Ryanzz May 23 '22 at 00:12
0

Firstly, I would point out the difference between the two examples you've shown. The method Change#change(Student)

public class Change {
  public void change(Student s) {
    s.name = "Fred";
  }
}

Compared to Change#dontChange(int)

public class Change {
  public void dontChange(int i) {
    i = 42;
  }
}

The most notable difference between these two methods is where they assign (=) the value they're passing. s.name vs i. Note the presence of the dot operator (.) indicating that there's access of an Object's field or method. This can help start the explanation of why change(Student) updates the value it assigns to as compared to dontChange(int).

There was reference of looking into the difference between pass-by-value and pass-by-reference in other answers, and that will be required information for WHY this happens. However, I think there should be a slightly deeper understanding of what a variable is in java for that to help explain it. The easiest explanation I find is that a variable in java is a number. Period. Always. Now that might seem weird, right? You obviously have an object when you do Student stu = new Student(), but that's only partially correct. You do instantiate (create/construct) an object, but the value stored in Student stu can actually be thought of as a number pointing to a spot in memory where stu's values are stored. There IS a difference in how these number are handled, but they are, in essence, all numbers.

Knowing this, you can work with the thought that values passed to a method in java are always passed-by-value. If you wanted to test this you could see the output of changing the body of Change#change(Student) to

public class Change {
  void change(Student s) {
    Student newStudent = new Student();
    newStudent.name = "Fred";

    s = newStudent;
  }
}

You may expect the output name to still be "Fred", but it should result in "Jane". We didn't modify the object that Student s refers to, we updated what the variable s points to. The difference being that in the original Change#change(Student) method you assigned the value "Fred" to the name field (s.name) of the object that Student s refers to.

When you call Change#change(Student) with the variable stu the parameter s's value becomes the same identifying number that stu points to, but the variables themselves are entirely different. They only, when s is initialized, have the same value (a number pointing to a space in memory).


It should be noted that assigning "Jane" and "Fred" to the Student's name field is actually assigning a reference to a String which represents "Jane" or "Fred" to the Student's name field. As the name field's type is, assumed to be, String which is not a primitive type. Meaning it's a reference to some String object in memory.

SquEdgy
  • 101
  • 2
0

What is happening here is passing by value and passing by reference. In Java all primitive types(int, char...) are passed by value to any method, this means the value of them are copied for the method to use.

Anything else like objects from classes you create are passed by reference. This means the contents of the object are not copied but the address of where that object is in memory is copied to the method. The value at this address(the original object) is then used within the method meaning changes to it are seen outside of the method.

To go into more detail and why this happens can get quite confusing as a beginner but other people have linked good articles to read. To put it simply in my own words.

Whenever you are using an object(non-primitive type) i.e Student. Java is actually seeing this as an address to that object but to keep things easier for the programmer Java doesn't make you declare this in any way. Any access to this object is automatically handled by Java to mean the value of the address you are using.