我希望以下程序的输出中有NullPointerException
,因为在go
方法中,c2
已为空。但它工作正常并打印200.为什么?
class CardBoard {
Short story = 200;
CardBoard go(CardBoard cb) {
cb = null;
return cb;
}
public static void main(String[] args) {
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
System.out.print(c2.story); // dout here
}
}
答案 0 :(得分:1)
您将go
函数的参数指向null,而不是c2
变量。 go
方法可能会在其执行中更改CardBoard
参数的内容(例如story
参数),但对象本身不会被“取消”。
答案 1 :(得分:1)
Java使用pass by value semantics进行方法调用。这意味着对c2
的引用值传递给go
方法,而不是引用本身。这样想吧。有4个内存插槽,其中3个包含指向main
中创建的对象的值,分别命名为c1
,c2
和c3
,另一个将保存传递到名为go
的{{1}}方法的值。调用该函数时,cb
中的值将复制到插槽c2
。然后cb
方法将值go
放入广告位null
。但是,这不会更改插槽cb
中的值 - 它仍然与方法调用之前的值相同。
答案 2 :(得分:1)
让我们说r2
是c2
的引用,让我们说123
是该引用的值。
所以r2
“拥有”123
,这只是c2's
位置。
现在,当您致电c1.go(c2)
时,会创建一个新的引用rN
,其中包含123
,并传递给该方法。当您执行c2 = null
时,参考rN
变为null
而不是c2
。
答案 3 :(得分:1)
在Java中,参数是按值传递的,而不是通过引用传递的,因此您不会修改变量c2
,而只是“传递”c2
所指向的对象。
也许如果您使用的是像C#这样的语言,您可以在java中执行此操作:
class CardBoard {
Short story = 200;
CardBoard go(byRef CardBoard cb) { // NOT REALLY ALLOWED, Compilation error
cb = null;
return cb;
}
public static void main(String[] args) {
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(byRef c2); // NOT REALLY ALLOWED, Compilation error
System.out.print(c2.story); // dout here
}
}
然后你会修改c2
本身,但你唯一可以修改的就是你传递的对象的内部状态(调用myObj.setSomething(x)
之类的东西)。
答案 4 :(得分:0)
所有这些对go方法之外的c2变量的内容没有影响
答案 5 :(得分:0)
要获得预期结果,请尝试使用
`System.out.print(cb.story);`
在go
cb 之后的nulling
方法内。
或强>
System.out.print(c3.story); // dout here
现在,在您的情况下,您将返回分配给null
的{{1}}。所以你没有修改c3
变量。
我发现关于这些疑虑的最佳解释是here
所有答案和评论都值得一读。
答案 6 :(得分:0)
我认为您被参考和对象的工作方式误解了
主要功能
CardBoard c1 = new CardBoard();
c1 |100| Address ---points to---> Memory address at location 100
CardBoard c2 = new CardBoard();
c2 |400| Address ---points to---> Memory address at location 400
CardBoard c3 = c1.go(c2);
c3 |600| Address ---points to---> Memory address at location 600
System.out.print(c2.story); // dout here
去功能
CardBoard go(CardBoard cb) {
cb |400| Address ---points to---> Memory address at location 400
New cb reference is created which also points to memory location where c2 is pointing(Note, cb and c2 are two different reference but pointing to same memory location)
cb = null;
Above line changed cb reference to null, still c2 is pointing to same memory location.
return cb;
}
因此,当返回go函数时,c2没有变化。
尝试在cb引用上更改故事变量,您将看到它也影响到c2变量。
cb在不同的方法堆栈中创建,然后创建c1,c2和c3