为什么在此代码中传递的引用不起作用?

时间:2014-11-18 10:36:01

标签: java

这让我发疯,因为它毫无意义。

在以下程序中,未正确设置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)

2 个答案:

答案 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()的那一刻,您将不再使用原始参考。

您无法将引用重新分配给其他对象。如果这样做,那么使用新对象所做的更改将不会反映在原始对象中