有没有办法保证真正的引用对象对调用函数没有副作用?
Is there a way to guarantee that a real referenced object has no side effect for a caller function?
我是最近学习的学生JAVA。
我根据我的 C++ 经验来学习这门语言。
所以我花了将近四天的时间才理解 c++ 和 java 在按值调用或引用方面的差距。
Java 是按值调用,因为调用函数将 引用类型变量 本身传递给被调用者。
理解了上面这句话的时候,突然想到一个问题
我的问题是...
我了解到按值调用的优点之一是没有副作用。
在JAVA中保证引用类型变量本身没有副作用
但是引用变量引用的真实对象可能会有副作用
在 returns 之后调用函数。
那么有没有办法保证堆内存中的引用对象对调用函数也没有副作用?
(如果我误解了 JAVA 机制,请告诉我)
================================
添加示例
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";
}
我希望boo()函数不修改p实例的成员变量(这里是p.name)
你可以这样做:
class Person{
final String name;
int age;
Person(String name, int age){
this.name = name;
this.age =age;
}
}
下面是一个小例子,说明如何传递对象的副本,确保原始对象不被修改。
当我使用复制构造函数时,原始对象的内部状态被保留,但是当我简单地声明 TestRef otherRef = testRef;
时,只有引用被复制,这样如果新对象被修改,原始对象也会被修改.
请注意,在这种情况下,我确实复制了字符串引用,因为字符串在 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++;
}
}
输出:
TestRef
TestRef
newString
我是最近学习的学生JAVA。
我根据我的 C++ 经验来学习这门语言。
所以我花了将近四天的时间才理解 c++ 和 java 在按值调用或引用方面的差距。
Java 是按值调用,因为调用函数将 引用类型变量 本身传递给被调用者。
理解了上面这句话的时候,突然想到一个问题
我的问题是...
我了解到按值调用的优点之一是没有副作用。
在JAVA中保证引用类型变量本身没有副作用
但是引用变量引用的真实对象可能会有副作用
在 returns 之后调用函数。
那么有没有办法保证堆内存中的引用对象对调用函数也没有副作用?
(如果我误解了 JAVA 机制,请告诉我)
================================
添加示例
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";
}
我希望boo()函数不修改p实例的成员变量(这里是p.name)
你可以这样做:
class Person{
final String name;
int age;
Person(String name, int age){
this.name = name;
this.age =age;
}
}
下面是一个小例子,说明如何传递对象的副本,确保原始对象不被修改。
当我使用复制构造函数时,原始对象的内部状态被保留,但是当我简单地声明 TestRef otherRef = testRef;
时,只有引用被复制,这样如果新对象被修改,原始对象也会被修改.
请注意,在这种情况下,我确实复制了字符串引用,因为字符串在 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++;
}
}
输出:
TestRef
TestRef
newString