一、描述

关于 Java 连等赋值,例如a=b=c;我们知道它是从右往左依次赋值的,其结果大致可以拆分为b=c;a=b;,但是当栈中没有持有变量的引用时,则会出现问题,例如:

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);拆分后:

n1 = new Node(nn, 3);
n1.n = n1; // 打印:
// n1:3 3
// n2:1 0

二、分析

1. 初始情况

2. 拆分的赋值

  • 首先n1指向node3
  • 然后n1.n指向node3自身,形成闭环
  • 所以结果打印n1:3 3 ;n2:1 0 ,这里很容易理解

3. 连等赋值

在开始赋值的时候因为 stack 里面并没有持有n1.n的引用,所以会现在 stack 中创建一个临时变量指向n1.n,如图:

所以在连等赋值之后变为:

所以最终n1.n = n1 = new Node(nn, 3);会打印n1:3 0;n2:1 3

  • 因为在执行完n1 = new Node(nn, 3);之后,stack 中的n1.n仍然指向原n1中的node
  • 在执行n1.n = n1的时候,两个n1所指示的对象已经不再相同,所以会等到以上结果;

三、总结

  • 对于以上问题之所以会出乎意料,就是因为原本以为是原子性的步骤,实际上是分布完成的;

  • 类似的问题其实在 Virtual Machine Specifications 中一定是能找到更为准确的答案的,如果你有兴趣可以自行查阅;

JAVA 连等赋值问题的更多相关文章

  1. atitit.java给属性赋值方法总结and BeanUtils 1.6.1 .copyProperty的bug

    atitit.java给属性赋值方法总结and BeanUtils 1.6.1 .copyProperty的bug 1. core.setProperty(o, "materialId&qu ...

  2. Jsp获取Java的重定向赋值(String)

    Jsp获取Java的重定向赋值(String) Java代码片段: //传递String request.setAttribute("msg", msg); //重定向 reque ...

  3. java.sql.Date赋值给了java.util.Date.转化成JSONArray时出错net.sf.json.JSONException: java.lang.reflect.InvocationTargetException

    net.sf.json.JSONException: java.lang.reflect.InvocationTargetExceptionat net.sf.json.JSONObject.defa ...

  4. properties文件属性值@Value注解为 java entity属性赋值

    一.使用@Value为 java entity类中的非static属性赋值 举个栗子,一目了然 1.1 properties文件 1.2 servlet.xml 文件增加的配置: 1.2.1 serv ...

  5. java中的赋值

    java中的赋值使用符号“=”. 按照java编程思想的解释:它的意思是“取等号右边的值,把它复制给左边”. 当然左边必须是一个明确的,已命名的变量. 基本类型: int a=2; int b=3; ...

  6. atitit.java方法属性赋值and BeanUtils 1.6.1 .copyProperty的bug

    atitit.java分配给属性值方法and BeanUtils 1.6.1 .copyProperty的bug 1. core.setProperty(o, "materialId&quo ...

  7. JAVA学习笔记之JAVA 对象引用以及赋值

      关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里,总觉得基本概念很模糊.后来才知道,在许多Java书中,把对象和对象的引用混为一谈.可是,如果我分不清对象与对象引用, 那实在没 ...

  8. JAVA变量初始化赋值null

     在Java中,null值表示引用不指向任何对象.运行过程中系统发现使用了这样一个引用时·可以立即停止进一步的访问,不会给系统带来任何危险. 1.如果是对象的field的话那么系统在初始化对象的时候会 ...

  9. java将一个List赋值给另一个List的4种方法

    编辑 删除 声明:ArrayList a, 仅仅只是声明了一个list变量,其未来作用相当于C++中的引用变量,亦或者相当于一个对象块的索引,但并未为其分配具体的完整的对象所需要的内存空间,其所分配的 ...

随机推荐

  1. Nuxt.js 从入门到放弃

    Nuxt 是 Vue 上的 SSR,也就是服务端渲染应用框架,可在很大程度上解决当前 SPA 和 CSR 的首页加载慢,不利于 SEO 的问题.本场 Chat 就将详细介绍 Nuxt 的使用以及相关概 ...

  2. 20175324 mycp

    具体描述: 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内容 ...

  3. postgrel执行VACUUM报VACUUM cannot run inside a transaction block

    在python脚本里执行: sql_gp1 = "VACUUM dwd_access_record_inout_temp" sql_gp2 = "delete from ...

  4. 搭建Windows故障转移群集

    标签:SQL SERVER/MSSQL SERVER/数据库/DBA/windows 概述 本章内容主要讲述搭建windows故障转移群集 环境: 域服务器:windows server 2008 R ...

  5. 【逆元】HDU-1576

    逆元: 同余方程 ax≡1(mod n),gcd(a,n) = 1 时有解,这时称求出的 x 为 a 的对模n的乘法逆元.(注意:如果gcd(a,n)如果不等于1则无解),解法还是利用扩展欧几里得算法 ...

  6. 使用MUI的日期控件引起的探索——HTML5 input类型date属性

    我写移动端的页面会用到MUI这个框架,个人觉得挺好用的,有很多实用的UI组件.当然坑还是有的,http://dev.dcloud.net.cn/mui/ui/ MUI官网,有兴趣的小伙伴可以看看 虽然 ...

  7. [Swift]LeetCode470. 用 Rand7() 实现 Rand10() | Implement Rand10() Using Rand7()

    Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a functio ...

  8. [Swift]LeetCode594. 最长和谐子序列 | Longest Harmonious Subsequence

    We define a harmonious array is an array where the difference between its maximum value and its mini ...

  9. [Swift]LeetCode861. 翻转矩阵后的得分 | Score After Flipping Matrix

    We have a two dimensional matrix A where each value is 0 or 1. A move consists of choosing any row o ...

  10. H5与企业微信jssdk集成

    H5与企业微信jssdk集成 一.公众号设置 注册企业微信,在应用与小程序栏目中,设置可信域名,配置公众号菜单.可信域名不得不说下,在最初开发时,认为设置并验证后,微信认证接口会实现跨域请求,其实并没 ...