0

我有基础课:

 public class SomeClass {

    private List<String> list = new ArrayList<String>();

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }   

}

在一种方法中,我有以下代码:

private void test(){

    SomeClass sc1 = new SomeClass();
    sc1.getList().add("a");
    sc1.getList().add("b");

    SomeClass sc2 = sc1;

    System.out.println(sc2.getList().size());

    sc1.getList().remove(0);
    System.out.println(sc2.getList().size());

    sc1=null;
    System.out.println(sc2.getList().size());

    sc2=null;
    System.out.println(sc2.getList().size());


}

我收到 :

  • 2
  • 1
  • 1
  • 空指针异常

但我虽然会收到:

  • 2
  • 1
  • 空指针异常
  • NullPointerException(如果之前的 NullPointerException 被捕获)

如果一个被引用的对象被设置为null,引用链接被破坏了?谢谢你的澄清

4

4 回答 4

12

如果引用的对象设置为 null,则引用链接断开?

没有将对象设置为null的概念,您只能将变量设置为null。这个说法:

sc1=null;

... 改变 的 值sc1 ,仅此而已

变量是一个简单的带有名字的存储位置。存储位置有一个值,对于非原始类型的变量,该值是一个引用。了解变量的值不是对象非常重要。这只是一个参考。

所以这个声明:

SomeClass sc2 = sc1;

只需声明一个新变量 ( sc2),它以与现有变量 ( ) 相同的值开始sc1。这两个变量是完全独立的——它们只是碰巧具有相同的值。

我喜欢把变量想象成一张纸。一张纸上可以有一些原始值,例如数字,或者它可以有一个家庭地址1。想象一下这些步骤:

  • 造房子
  • 将那所房子的地址写在一张纸上(sc1
  • 将文字复制sc1到另一张纸上(sc2
  • 擦掉上面的地址sc1
  • 访问地址所在的房子sc2

这与您在这里所做的类似......并且显然擦掉价值sc1不会影响房子或这sc2张纸。

现在至于为什么你看到 2 然后 1 ......想象这些步骤:

  • 造房子
  • 将那所房子的地址写在一张纸上(sc1
  • 用来找房子sc1,把两个包裹放在门口
  • 将文字复制sc1到另一张纸上(sc2
  • 用来找房子sc1,大声喊出你找到了多少包裹
  • 用来找房子sc1,拿走一个包裹
  • 用来找房子sc2,大声喊出你找到了多少包裹

第一次你会喊 2,然后你会喊 1。你并没有改变纸片上的值——你通过添加或移除包裹来改变房子本身。


1我知道引用不一定是内存地址。这纯粹是为了类比,我发现这是有帮助的。

于 2013-01-23T17:31:35.357 回答
5

当您设置sc2为 时sc1,您复制参考。这两个变量引用同一个对象,但它们不会成为同一个变量。设置sc1null不会改变sc2- 它引用同一个SomeClass对象,所以NullPointerException当你访问它的getList()方法时没有。

于 2013-01-23T17:30:51.600 回答
0

让我们看一下事情指向的地方:

SomeClass sc1 = new SomeClass();

在这里,您有 sc1 指向(引用)您新创建的类,而 sc2 甚至不在图片中。

SomeClass sc2 = sc1;

你有 sc1 和 sc2 指向同一个对象。

sc1=null;

您的对象仍然完好无损,因为 sc2 仍然指向它。Sc1 为空并且不指向任何东西。由于 sc2,对象本身不符合垃圾收集条件。

sc2=null;

现在你有 sc1 和 sc2 都指向任何东西。您的对象没有对它的引用,垃圾收集器将(最终)释放它。

正如您一步一步看到的那样,“引用链接已损坏”,但对象本身并没有真正受到影响,直到其所有引用都丢失。只要你对它有单一的引用,对象就是活着的。

于 2013-01-23T17:35:05.437 回答
0

如果你做SomeClass sc1 = new SomeClass(),你会做类似的东西sc1->OBJECT。做sc2=sc1,就像做sc2->sc1->OBJECT,或者sc2->OBJECT。因此更改 sc1 引用不会更改 sc2。

于 2013-01-23T17:32:19.253 回答