JAVA 连等赋值问题
一、描述
关于 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 连等赋值问题的更多相关文章
- atitit.java给属性赋值方法总结and BeanUtils 1.6.1 .copyProperty的bug
atitit.java给属性赋值方法总结and BeanUtils 1.6.1 .copyProperty的bug 1. core.setProperty(o, "materialId&qu ...
- Jsp获取Java的重定向赋值(String)
Jsp获取Java的重定向赋值(String) Java代码片段: //传递String request.setAttribute("msg", msg); //重定向 reque ...
- 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 ...
- properties文件属性值@Value注解为 java entity属性赋值
一.使用@Value为 java entity类中的非static属性赋值 举个栗子,一目了然 1.1 properties文件 1.2 servlet.xml 文件增加的配置: 1.2.1 serv ...
- java中的赋值
java中的赋值使用符号“=”. 按照java编程思想的解释:它的意思是“取等号右边的值,把它复制给左边”. 当然左边必须是一个明确的,已命名的变量. 基本类型: int a=2; int b=3; ...
- atitit.java方法属性赋值and BeanUtils 1.6.1 .copyProperty的bug
atitit.java分配给属性值方法and BeanUtils 1.6.1 .copyProperty的bug 1. core.setProperty(o, "materialId&quo ...
- JAVA学习笔记之JAVA 对象引用以及赋值
关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里,总觉得基本概念很模糊.后来才知道,在许多Java书中,把对象和对象的引用混为一谈.可是,如果我分不清对象与对象引用, 那实在没 ...
- JAVA变量初始化赋值null
在Java中,null值表示引用不指向任何对象.运行过程中系统发现使用了这样一个引用时·可以立即停止进一步的访问,不会给系统带来任何危险. 1.如果是对象的field的话那么系统在初始化对象的时候会 ...
- java将一个List赋值给另一个List的4种方法
编辑 删除 声明:ArrayList a, 仅仅只是声明了一个list变量,其未来作用相当于C++中的引用变量,亦或者相当于一个对象块的索引,但并未为其分配具体的完整的对象所需要的内存空间,其所分配的 ...
随机推荐
- mysql5.7.X版本only_full_group_by问题解决
一.出错原因 最近因为开发数据库与部署数据库版本不同,带来了几个问题,其中only_full_group_by问题是之前没有遇到的. 具体报错如下 [Err] 1055 - Expression #1 ...
- mysql命名规范
1.数据库表命名规范: (1)表名前应该加上前缀,表的前缀一个用系统或模块的英文名称缩写,前缀全部大写或首字母大写,表名中包含的单词首字母大写. (2)数据库表名应该有意义,并且易于理解,最好使用可以 ...
- Centos7 通配符HTTPS证书申请 实测 笔记
环境: 免费通配符HTTPS证书网址: https://letsencrypt.org/ 1.下载证书申请工具 [root@centos ~]# mkdir /opt/letsencrypt -p [ ...
- NPOI 修改指定单元格字体颜色
//创建一个字体颜色 IFont font = hssfworkbook.CreateFont(); //红色 font.Color = HSSFColor.Red.Index; //样式 ICell ...
- activiti数据库表结构剖析
1.结构设计 1.1. 逻辑结构设计 Activiti使用到的表都是ACT_开头的. ACT_RE_*: ’RE’表示repository(存储),RepositoryService接口所操作的 ...
- aarch64的架构:unrecognized command line option '-mfpu=neon'
不用添加这个'-mfpu=neon'的编译器选项了,因为这个架构下neon是默认启动的. 参考: https://lists.linaro.org/pipermail/linaro-toolchain ...
- 问题:win7下配置好服务器就是不能查询数据库。(已解决)
我用C写访问mysql的CGI程序,可以执行. 但是,当我写好网页再去访问这个CGI,出现下面的错误 我的环境是:IIS作为服务器,MYSQL数据库,VC++6.0写CGI. 跟踪了一下,发现只要我调 ...
- 串口RS232和485通信的波形分析
一.串行数据的格式 异步串行数据的一般格式是:起始位+数据位+停止位,其中起始位1 位,数据位可以是5.6.7.8位,停止位可以是1.1.5.2位. 起始位是一个值为0的位,所以对于正逻辑的TTL电平 ...
- 解决idea中 mvn项目导了包找不到包的问题
----------------------------------------分割线--------------------------------------------------------- ...
- Docker常用命令(一)
[转]原始出处:http://zxx287856774.blog.51cto.com/3417296/1665264 docker中 启动所有的容器命令 docker start $(docker p ...