提问人:WindTorn 提问时间:6/9/2014 最后编辑:Sotirios DelimanolisWindTorn 更新时间:6/9/2014 访问量:75
反直觉对象参数行为
Counter Intuitive Object Parameter Behaviour
问:
我很清楚 Java 按值传递参数,以及由于对象作为引用保存在可变对象中,因此当这些值可变时可以更改对象值。我还理解的是,类 String 包含不可变的对象。因此,为了测试我的理解,我决定编写一些代码,将对象作为参数传递给方法,更改其字符串和 int 变量,然后打印它。我预计,由于参数只是一个副本,这些更改不会影响传入的变量。作为参数传入对象是否不是将整个对象复制到新变量中,而只是传递该对象引用?这与几个消息来源告诉我的情况相反。以下是有问题的代码:
public class Test {
public int testVar = 20;
public String testString = "Hello";
public static void testCheck(Test test){
test.testString = new String("GoodBye");
test.testVar = 10;
}
public void printTest(){
System.out.println("testVar: " + testVar + " testString: " + testString);
}
public static void main(String[] args) {
Test test1 = new Test();
test1.printTest();
testCheck(test1);
test1.printTest();
}
}
输出:
testVar: 20 testString: Hello
testVar: 10 testString: GoodBye
预期:
testVar: 20 testString: Hello
testVar: 20 testString: Hello
提前致谢。
答:
0赞
Martin Dinov
6/9/2014
#1
您正在将引用的副本传递给原始对象。实际上,您正在传递原始对象的引用,依此类推:
testCheck(test1);
您正在修改对象的属性/变量。test1
1赞
Sotirios Delimanolis
6/9/2014
#2
一些概念:
- 对象是具有数据和行为的结构。
- 变量是存储值的构造。
- 对象引用是引用对象的值。
- 引用类型(所有非基元类型的类型)的变量将对象引用存储为其值。
- 当您访问字段或从变量调用方法时,JVM 会取消引用对象引用的值,获取对象,并为您执行访问或调用。
最后一点是你在方法中所做的。也testCheck
- 方法参数是在方法定义中声明的变量。
- 方法参数是在调用方法时要绑定到方法参数的值。
- Java 传递 (by-value) 并将对象引用的值绑定到 method 参数。
作为参数传入对象是否不复制整个对象 到一个新变量中,只需传递该对象引用?
这句话没有多大意义。您作为参数传递的是一个值。该值是对象引用,而不是对象。在方法中,取消引用该对象引用以访问字段并调用所引用对象的方法。
1赞
shmosel
6/9/2014
#3
在 Java 中,参数总是按值传递的,所以实际上是 的副本。您犯的错误是复制对象变量不会复制对象;它将引用复制到同一对象。由于您要更改同一对象实例上的字段,因此两个引用都会看到新状态。相比之下,当你“更新”一个不可变的对象变量时,比如 ,你只是在引用一个新的对象实例。test
test1
String
顺便说一句,很少有充分的理由创建一个,而不仅仅是分配一个字符串文字。在这种情况下绝对没有。new String
评论