Does Java pass references or values or both? Is my explanation correct? [duplicate]

I had a discussion with someone that Java is pass-by-value exclusively or not. The following code made me think about it:

public static void main(String [] args){
     Student studentMain = new Student();
     studentMain.setName("Tristan");

     changeName(studentMain);
     studentMain.getName().equals("Yannick"); //This is true

     changeStudent(studentMain);
     studentMain.getName().equals("Vic"); //This is false
}

private changeName(Student studentParam1){
     studentParam1.setName("Yannick");
}

private changeStudent(Student studentParam2){
     studentParam2 = new Student();
     studentParam2.setName("Vic");
}

If Java was purely pass by reference then this code would produce "true" twice, but it doesn't. So I came to the following logic:

Since changeName() did change the original Object (studentMain), it has to point to the same memory. But since changeStudent() didn't change studentMain, this means it doesn't directly point to that same memory.

I consider it as a chain:

memory <- studentMain <- studentParam1

memory <- studentMain <- studentParam2

In changeName() you change an attribute of studentParam1, which passes this trough to studentMain, which in turn passes this to the memory. Your chain remains the following:

memory <- studentMain <- studentParam1

In changeStudent() you don't change an attribute, but studentParam2 itself. It now points to a new place in memory for the newly formed Student. The original reference (studentMain) is unchanged because that one still points to the original piece of memory. You have broken the chain and made a new one. At the end of the method, the newly formed reference (studentParam2) is lost to scope and will be taken care of by the Garbage Collector. Your chain becomes:

memory <- studentMain

otherMemory <- studentParam2

Pass-by-value means that a copy of the value is passed. Pass-by-reference means THE reference is passed (which implies there is one reference that is shared over the entire program). I conclude however that it is actually some hybrid-form. you pass-by-value, but the value itself is a reference. So a copy of the initial reference is passed.

I'm looking forward to your thoughts on the matter.

PS: This conclusion is about Objects, not primitive datatypes.


Java is always pass-by-value - just sometimes a reference is the value.

In a method you have a local variable with provided reference so changing property of object underneath this reference will modify original object.

On the other hand if you will reassign the local variable then the original one will not change (still is containing the first reference) and the original object is also not modified