一、描述

关于 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. 我的 FPGA 学习历程(10)—— 实验:数码管驱动

    根据黑金 AX301 手册,数码管位选信号命名为 SEL[5:0],其中 SEL[5] 对应最左边的数码管,而SEL[0] 对应最右边数码管:作为约定,在下面的描述中我们对应的称之为数码管 5 和数码 ...

  2. company_base_info_staff_job

    "company_base_info_staff_job": { "engine": "python script", # datax or ...

  3. DEDECMS织梦文章摘要批量更改方法

    我们建站有时候需要直接把数据库导入,只要修改一下基本的名称信息就可以直接用,但是遇用到一些问题.比如文章摘要不会随着文章内容的更新而更新.织梦(dede)在添加文章的时候会自动生成文章摘要,如果重新修 ...

  4. python爬取网页内容demo

    #html文本提取 from bs4 import BeautifulSoup html_sample = '\ <html> \ <body> \ <h1 id = & ...

  5. pip离线安装依赖包

    pip安装离线本地包 导出本地已有的依赖包 pip freeze > requirements.txt 将依赖包下载到本地 # 下载到当前目录,指定pip源 pip download -r re ...

  6. javascript中的函数节流和函数去抖

    带着问题去尝试 首先我们要知道为什么要用到函数节流和函数去抖?我们带着以下的疑问来进行分析! 1.比如搜索框,你会用到什么事件(change.blur.keyup等)?去做什么效果?2.再比如scro ...

  7. vue-router路由学习总结

    vue路由 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  8. win10 anaconda安装后使用报错“Original error was: DLL load failed: 找不到指定的模块”

    报错:Original error was: DLL load failed: 找不到指定的模块. 环境变量需要添加3个 然后就okay了.

  9. 动态添加echarts

    本次只贴js和jsp代码 jsp只需添加一个div即可, <div class="fLayout-right-box"> <hy:layoutArea width ...

  10. RabbitMQ 集群原理和完善

    一.RabbitMQ集群方案的原理 RabbitMQ这款消息队列中间件产品本身是基于Erlang编写,Erlang语言天生具备分布式特性(通过同步Erlang集群各节点的magic cookie来实现 ...