I'm a student who recently learns JAVA.
I approaches this language based on my C++ experience.
So It took me almost four days to understand the gap between c++ and java in terms of the call-by-value or reference.
Java is call-by-value because a caller function passes a reference type variable itself to a callee.
When I understood the above sentence, a question comes to my mind suddenly.
My question is that...
I've learned that one of the call-by-value's advantages is no side effect.
In JAVA, It is guaranteed that a reference type variable itself has no side effect.
But a real object referenced by the reference variable may has side effect
after returns to a caller function.
So is there a way to guarantee that referenced object in heap memory also has no side effect for a caller function?
(And if I misunderstood the things around JAVA mechanism, please tell me)
==============================
Add a example
class Person{
String name;
int age;
Person(String name, int age){
this.name = name;
this.age =age;
}
}
public static void foo(){
Person p = new Person("haha", 17);
System.out.println(p.name); // haba
boo(p);
System.out.println(p.name); // hoho, but foo() wants original value "haha"
}
public static void boo(Person p){
p.name = "hoho";
}
I want boo() function not to modify the member variable(p.name in here) of the p instance.
Below is a small example of how you can pass copies of objects, ensuring that the original object is not modified.
When I use the copy constructor, the internal state of the original object is preserved, but when I simply state TestRef otherRef = testRef;
only the reference is copied such that if the new object is modified, so is the original.
Note that in this case I do copy the String reference since strings are immutable classes in java.
public class Main {
public static class TestRef {
public String a;
public int b;
//Copy constructor
public TestRef(TestRef other) {
this(other.a, other.b);
}
public TestRef(String a, int b) {
this.a = a;
this.b = b;
}
}
public static void main(String[] args) throws IOException, TransformerException {
TestRef testRef = new TestRef("TestRef", 1);
//Using copyConstructor to make deep copy of object
System.out.println(testRef.a);
TestRef deepCopy = new TestRef(testRef);
modifyClass(deepCopy);
System.out.println(testRef.a);
//Shallow copy
TestRef otherRef = testRef;
modifyClass(otherRef);
System.out.println(testRef.a);
}
public static void modifyClass(TestRef testRef) {
testRef.a = "newString";
testRef.b++;
}
}
OUTPUT:
TestRef
TestRef
newString