为什么输出结果是3?
为什么输出结果是3?——这是我自学Java时遇到的一个问题,纠结到了兄弟连才找着一个理由,虽然没经过“官方”认证,但我说服我自己了~~~想知道是什么问题?那就往下看。
我们JAVA03班有一种很好的制度,每天请一位学员分享一些知识,可以是任何内容。有的学员讲自家地界风土人情,有的学员介绍与老外不得不说的故事,有的学员进行现场高端访谈,还有经济学、投资学专场……很丰富,也相当有意思。上周四轮到我分享了,我实在没什么拿的出手的,就把我学习JAVA过程中遇到的问题讲了几个,并且坦白了我解决问题的办法,实在很无聊。这次轮到我写战地日记了,我还是没什么拿得出手,于是我把上周四分享的内容写了出来。
第一个问题:流氓的“默认”
学习了继承后,做练习,我发现写的子类总是出错。想起课堂上老师介绍的一个内容,父类中写一个空参的构造器,会减少麻烦。因为系统会“默认”要求子类构造器访问父类的空参构造器。
于是我开始实验。
什么实验?
相当无聊的实验!!!
我把类中是否写构造器,分为了四种情况:
1) 不写构造器;
2) 写一个不带参数的构造器;
3) 写带参数的构造器;
4) 既写不带参数的构造器,也写带参数的构造器。
子类相应也有这四种情况(子类不使用super),父子类一一对应,有16种组合,所以我做了16次实验,看子类在什么情况下会编译不通过。
结果:父类中在第3种情况时,子类的四种写法都会编译不通过。父类其它情况时子类编译通过。
这个结果验证了课堂上的两条结论:
结论一:如果子类构造器没有写主动访问父类的语句,系统就会“默认”让子类的构造器访问父类的空参构造器;
结论二:如果类中不写任何构造器,系统就会“默认”提供一个空参的构造器。如果写了构造器,系统就不会再提供这个空参的构造器。
为了记住这两条结论,我把这两条结论以联想记忆的风格翻译了一下:
1)一个类中必须有构造器。(主动写的,或被偷偷塞的)
2)子类必须去访问父类的构造器。(主动去,或被劫去)
相当无聊是吧!
更无聊的来了!!!
第二个问题:为什么输出结果是3?
请看以下语句,判断输出结果:
int a = 3;//(1)
a = a++;//(2)
System.out.println(a);//(3)
有猜4的吗?
有猜3的吗?
猜3的同志们,你们猜对了!
为什么不是4?有些人一看第二句——加加在后,先赋值,再加加,结果应该是4。
可惜,不对!
经过我一翻纠结的不能再纠结的实验:
/************
a = a++ + a++;
a = a++ + a++ +
a++;
a = a++ + a++ + a--;
……
************/
我找到了一个很能说服我自己的理由:
“自增运算符的优先级仅次于括号,等号的优先级差不多排到了最后”这是一条强有力的论据。所以a=a++; 先进行的是等号右边的算式a++,然后再将结果赋值给左边的变量。
详细分析一下a=a++;
第一步:a++
自增运算有两个步骤:++在a的后面,所以第一步将变量a的值3取出来放到CPU中等待后续计算;第二步,变量a变成了4,自增运算结束。这两步中间没有其他过程。
第二步:a=运算结果
运算结果是神马?cpu里面存放的东西只有一个3,所以这个3就是运算结果。变量a的值又从上一步的4变回了3!!!
如果有人在eclipse软件中写上这样两条语句:
a=a;
a=++a;
会发现这两条语句都有警告:“这个赋值语句对变量a没有作用”。而a=a++没出现任何警告。
a=a:把a值3提取出来重新赋给a,没任何意义!
a=++a:变量a的值先变为4,然后把变量a的值4提取出来重新赋值给a,同样没有意义。
a=a++呢?最后一步的赋值操作是将3赋值给已经变成4的a,这其中变量的值有变化。不像上面两种情况,最后的赋值操作都是把值从a取出来再重新赋给a。所以这条语句没有警告。
有道理没?相当有道理!——我自己这么认为。
无聊不?相当无聊!——大家都这么想。
这种实验我还做过很多,虽然无聊,我也会为自己一次次无聊的、小小的成就而偷偷得意。如果我从事了软件行业,这些实验还会继续陪伴我。
我相信小小的成就也可以激励一个人。当你的工作没有起色时,找些无聊的实验做一做吧,偷偷得意一下,很快就会精神抖擞起来!
这是我的第一篇战地日记,希望兄弟连越来越好!
原文地址:
阅读(450) | 评论(0) | 转发(0) |