在Java中,对象引用用于按引用调用,变量用于按值调用。
以下是一个例子:
class Foo{
int x;
int y;
}
public class CallByRef {
public static void main(String[] args) {
Foo foo = new Foo();
foo.x=5;
foo.y=10;
System.out.println(foo.x+", "+foo.y);
getFoo(foo);
System.out.println(foo.x+", "+foo.y);
}
static void getFoo(Foo f){
f.x=2;
f=new Foo();
f.x=10;
}
}
输出:
5, 10
2, 10
为什么会这样?
当我用x
修改其值时, f.x=10
应为10
f=new Foo()
在堆中创建新对象而不指向prevoise引用是否正确?
答案 0 :(得分:1)
在方法getFoo
中,变量f
是一个局部变量。
当您从getFoo(foo)
致电main
时,此变量确实是指foo
。
但是一旦设置f = new Foo()
,它就会引用另一个对象。
因此,此时,更改f.x
不会影响foo.x
。
答案 1 :(得分:0)
以下是您的案例中作为示例发生的基本描述
// Creating a new object of Foo
// The variable foo now stores a VALUE!!! to the memory where the
// Instance of foo is stored
Foo foo = new Foo();
// accesing the instance of Foo over the value to the reference in the memory
// and set x to 5
foo.x = 5
// accesing the instance of Foo over the value to the reference in the memory
// and set y to 5
foo.x = 10
// Print out x and y of the instance of Foo where the value of the reference to memeory points to
System.out.println(foo.x+", "+foo.y);
现在让Foo做什么
// The instance f of Foo holds the value to the reference in the memory
// Lets call it 1234567 as example
static void getFoo(Foo f){
// The object in the memory 1234567 is going to have x changed
f.x=2;
// The VALUE of the reference is changed, lets say it now refers to the memory 123456789 where a new instance of Foo is stored now
f=new Foo();
// The object in the memory 123456789 is going to have x changed
f.x=10;
}
让我们回到你的上一个输出以及它现在打印的内容
// So in your getFoo() Call your first action was to change the value of x
// on the object with the value to the reference which you gave as a parameter
// hence it prints 2
// The new instance of the Object Foo that is stored somewhere else in the memory should be garbage collected soon, since no variable actually holds the VALUE to the reference anymore
System.out.println(foo.x+", "+foo.y);
要理解的最重要的部分是,对变量或参数中的对象的引用实际上作为值存储到内存中。因此,你的getFoo()方法只是改变了对象实例的引用值,但是永远不能改变引用本身
答案 2 :(得分:0)
我认为第一种情况对您来说很清楚,即价值5,10
。
之后通过调用getFoo()
方法并传递相同的对象foo
作为参数传递。在getFoo()
方法中,同一对象(foo)
的实例变量值更改为2.但之后,它使用new
键工作创建新对象并分配另一个值。
即
foo => x=2(new value) and y=10(not changed, so it takes old value)
f => x=10 and y=0(not assigned)
你正在打印foo的价值。
因此结果为2,10