【jFresH_MaN】100分问一个非常基础的问题,大家踊跃回答哦

jfreshman 2005-03-27 04:11:30
int i=0;
i=i++;
i=?

很简单吧
先给出答案
然后说出为什么?

虽然自己接触java时间也不短了,但是刚才看到那个帖子里的这个问题觉得很费解
看到答案我就觉得很奇怪,测试了一下果然是那样
看来自己真的还很菜,希望哪位能把我说懂

原来的jFresH_MaN的帐号没分了,所以用马甲,各位见谅,欢迎讨论
100分!
...全文
795 92 打赏 收藏 转发到动态 举报
写回复
用AI写文章
92 条回复
切换为时间正序
请发表友善的回复…
发表回复
u94586813 2005-05-31
  • 打赏
  • 举报
回复
0
FBugFramework 2005-04-14
  • 打赏
  • 举报
回复
Mark
Banned 2005-04-02
  • 打赏
  • 举报
回复
参考第二版的Java语言规范第14,15章有如下结论:

程序的运行基本上是语句执行的过程。

有一种语句叫表达式语句,表达式语句通过评估
表达式的值得以执行。

有一种表达式叫简单赋值表达式。
其结构如下:

left-hand = righ-hand

简单赋值表达式的评估步骤如下:
1 对left-ha估以nd评确定一个变量。
2 对right-hand评估以得到一个值。
3 将步骤2得到的值保存进步骤1所确定的变量中。

简单赋值表达式的值即是 赋值以后,left-hand所确定的变量的值。

有一种表达式叫后增表达式。
其结构为:
operand ++

后增表达式的评估步骤如下:
1 对operand评估以确定一个变量。
2 对步骤1中的变量进行增1操作。

后增表达式的值是 没有增1操作前operand所确定的变量的值。

回过来分析(i的初始值为0)
i=i++

i=i++ 是简单赋值表达式,所以其评估过程是

1 确定变量i
2 评估i++
2.1 确定变量i
2.2 i增1,这时i的值为1
3 i++表达式的值是0,于是i的值被赋为0

如上分析,最后i的值为0。

gengqi 2005-03-28
  • 打赏
  • 举报
回复
学习
Hodex 2005-03-28
  • 打赏
  • 举报
回复
我也学到了不少!!

thanks to all!!
jFresH_MaN 2005-03-28
  • 打赏
  • 举报
回复
看来这个问题已经得到完美的答案了
借着这个贴,再问问大家
由谁仔细研究过<<Inside JVM>>这本书

那上面是不是对于这方面是不是介绍比较多?

另外希望以后Java版都点技术上的讨论,这样人气才会旺。
谢谢大家,我又学到了不少!!
Hodex 2005-03-28
  • 打赏
  • 举报
回复
DanielYWoo(绿色毒汁)所言极是
opencsdn 2005-03-28
  • 打赏
  • 举报
回复
0
jFresH_MaN 2005-03-28
  • 打赏
  • 举报
回复
to java_ak47(十元钱便宜货)
答案是1嘛?
请运行一下再说
:)
cuilichen 2005-03-28
  • 打赏
  • 举报
回复
嗯,同意楼主的总结,
真应该注意这些细节的问题,
免得出现错误还不知道,呵呵。
airskys 2005-03-28
  • 打赏
  • 举报
回复
长见识
估计应该是对象引用的问题
java_ak47 2005-03-28
  • 打赏
  • 举报
回复
结果就是1,干嘛问那么多为什么呢......
----1000000个为什么
jFresH_MaN 2005-03-28
  • 打赏
  • 举报
回复
to fxbird(飞翔鸟)
这个就是里那个问题
我看见有很多在你那个帖子里说的不对
想让大家一起针对这个问题讨论一下
所以开贴又问,这样就能让大家都对jvm的运行机制有个深入的了解
jFresH_MaN 2005-03-28
  • 打赏
  • 举报
回复
大家说的不错

DanielYWoo(绿色毒汁)
说的意思是=表达式右边式在栈里面计算的
这个结论和昨天讨论的结论式一样的

也就是说在++之前已经返回了计算的值给了等号左边,所以后面的++是在栈里的临时变量进行计算的
,这样就不会影响原来的变量值。

我想这个应该是最终结论了吧?

大家还有什么看法?
fxbird 2005-03-28
  • 打赏
  • 举报
回复
这不就是我提的那个问题吗
huangmaomao 2005-03-28
  • 打赏
  • 举报
回复
当年汇编没学会,吃老亏了,听了各位切磋小弟也学到不少,谢谢楼主
ProgrammerPro 2005-03-28
  • 打赏
  • 举报
回复
ublic class Test {
public static void main(String[] args){
int i = 0;
i = i++;
System.out.println(i);
int j = 0;
j = (j++);
System.out.println(j);
}
}


//JDK 1.4.2_b05
//javac Test.java
//java Test

//out println
0
0
DanielYWoo 2005-03-28
  • 打赏
  • 举报
回复
>>JAVA的有的是编译期的,比如

sorry, should be

JAVA的优化有的是编译期的,比如

nbamjzhldm 2005-03-28
  • 打赏
  • 举报
回复
up
DanielYWoo 2005-03-28
  • 打赏
  • 举报
回复
>>关键原因是Java编译器对一个表达式的处理总是: "把operand入栈进行运算,最后弹栈赋值给表达式结果",就算是其实这个过程是多余的,Java编译器也傻乎乎的这么做。

估计Java的EBNF
<表达式>::=([+|-]<项>)的正闭包
<赋值语句>::=<表识符>=<表达式>

那么赋值语句i=i++;的语法树推导可能是
赋值语句
=>
i = <表达式>
=>
i=<项>
=>
这时,<项>可以推到成i++,这表示"表达式i"计算完后,对i自增,注意,是表达式,不是赋值语句!!!

因此可以知道,
在Java里,i=i++;的语法树是
i = i++
/ | \
i = <表达式>
所以编译器完成语法分析后,代码生成相对应产生的byte code是,入栈(对应语法树右边的i),变量自增(对应<标示符>++),出栈赋值(对应赋值语句,把表达式在栈上运算的结果放入内存)的三条byte code执行码

JAVA的有的是编译期的,比如
for () {
int i=0;
i = ...;
}
编译出来的结果和
int i=0;
for () {
i = ...;
}
一样(避免N次 常量0入栈,弹栈对i赋值 的两个执行码操作)
有的是真正执行的时候,VM做的优化,这里,我猜测VM应该有优化吧?
加载更多回复(72)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧