这让我发疯,因为它毫无意义。
在以下程序中,未正确设置b
变量。 b
应该通过副本传递,但由于b
是对象的引用,这应该可以正常工作,但它不会。
public class A {
private B b;
public void foo() {
System.out.println("the value of b is : " + b);
bar(b);
System.out.println(b.getName());
}
private void bar(B b){
if (b == null) b = new B();
b.setName("me");
}
public class B {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class MainTest {
public static void main(String args[]) {
A a = new A();
a.foo();
}
}
执行后我收到此错误:
the value of b is : null
Exception in thread "main" java.lang.NullPointerException
at test.A.foo(A.java:12)
at test.MainTest.main(MainTest.java:6)
答案 0 :(得分:1)
当您传递对方法的引用时,您将传递该引用的副本。因此,如果引用是可变对象,则该方法可以改变该对象。但是,如果您更改方法中的引用,则调用者不会看到此更改。
private void bar(B b){
if (b == null) b = new B(); // this cannot change the reference passed by the caller
b.setName("me"); // this can update an instance of B passed from the outside
}
要使此方法符合预期,您应该确保永远不会将其传递给空引用,或者应该返回新创建/修改的实例:
private B bar(B b) {
if (b == null) b = new B();
b.setName ("me");
return b;
}
然后将返回的引用分配给原始变量:
b = bar(b);
答案 1 :(得分:0)
是的。由于if (b == null) b = new B();
,预计会出现NPE。如果您处理传递给bar()
的原始参考,那很好。您执行new B()
的那一刻,您将不再使用原始参考。
您无法将引用重新分配给其他对象。如果这样做,那么使用新对象所做的更改将不会反映在原始对象中。