JAVA 連等賦值問題

1、描述

關於 Java 連等賦值,例如a=b=c;咱們知道它是從右往左依次賦值的,其結果大體能夠拆分爲b=c;a=b;,可是當棧中沒有持有變量的引用時,則會出現問題,例如:html

public class Node {
  int i;
  Node n;

  Node(int i) {
    this.i = i;
  }

  Node(Node n, int i) {
    this.i = i;
    this.n = n;
  }

  @Override
  public String toString() {
    return i + " ";
  }

  public static void main(String[] args) {
    Node nn = new Node(0);
    Node n1 = new Node(nn, 1);
    Node n2 = n1;

    n1.n = n1 = new Node(nn, 3);
    System.out.println(n1.toString() + n1.n.toString());
    System.out.println(n2.toString() + n2.n.toString());
  }
}

// 打印:
// n1:3 0 
// n2:1 3

若是將以上n1.n = n1 = new Node(nn, 3);拆分後:java

n1 = new Node(nn, 3);
n1.n = n1;

// 打印:
// n1:3 3  
// n2:1 0

2、分析

1. 初始狀況

初始化

2. 拆分的賦值

分步賦值

  • 首先n1指向node3
  • 而後n1.n指向node3自身,造成閉環
  • 因此結果打印n1:3 3 ;n2:1 0,這裏很容易理解

3. 連等賦值

在開始賦值的時候由於 stack 裏面並無持有n1.n的引用,因此會現在 stack 中建立一個臨時變量指向n1.n,如圖:node

連等賦值1

因此在連等賦值以後變爲:oracle

連等賦值2

因此最終n1.n = n1 = new Node(nn, 3);會打印n1:3 0;n2:1 3ide

  • 由於在執行完n1 = new Node(nn, 3);以後,stack 中的n1.n仍然指向原n1中的node
  • 在執行n1.n = n1的時候,兩個n1所指示的對象已經再也不相同,因此會等到以上結果;

3、總結

  • 對於以上問題之因此會出乎意料,就是由於本來覺得是原子性的步驟,其實是分佈完成的;this

  • 相似的問題其實在 Virtual Machine Specifications 中必定是能找到更爲準確的答案的,若是你有興趣能夠自行查閱;3d

相關文章
相關標籤/搜索