黑马程序员——03Java换行符和i=i++的分析

由以上分析可知,java的换行符可以是’\n’或’\r\n’或’\r’,即可能是两个字符也可能是一个字符。而在实际编程中最好用System.getProperty("line.separator")来获取当前平台的换行符,这样跨平台性更好。回车和换行的有趣历史

在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。

这就是“换行”和“回车”的来历,’\r’和’\n’也就是(回车”return和“换行”newline)的首字母。

后来,计算机发明了,这两个概念也就被搬到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。

Unix系统里,每行结尾只有“<换行>”,即“\n”;Windows系统里面,每行结尾是“<回车><换行>”,即“\r\n”;Mac系统里,每行结尾是“<回车>” 即“\r”。一个直接后果是,Unix/Mac系统下的文件在Windows里打 开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。2,Java中i=i++的特殊处理

class  Add{    public staticvoid main(String[] args){            int x=0,z=0;            for (inty=100;y>100 ;y-- ){                        x=x++;                        z=++z;            }            System.out.println("x="+x+",z="+z);     }} 

在处理i=i++时,java虚拟机和VC的处理机制不同,利用javap -c Add命令进行反编译,得到下图,由此可分析出JVM的实际运行过程。

解释上图反编译出来的字节码指令内容:

0:把语句x=0中的常量0压入操作栈栈顶,此时栈顶为0;

1:弹出此时栈顶int型常量(即0)存储到位置为1的局部变量(即变量x)中,此时x=0;

2:把语句z=0中的常量0压入操作栈栈顶,此时栈顶为0;

3:弹出此时栈顶int型常量(即0)存储到位置为2的局部变量(即变量z)中,此时z=0;

4:把语句y=0中的常量0压入操作栈栈顶,此时栈顶为0;

5:弹出此时栈顶int型常量(即0)存储到位置为3的局部变量(即变量y)中,此时y=0;

6:从位置为3的局部变量(即变量y)中取出int类型的值装载到操作栈栈顶;

7:将byte类型的常量(即100)转换为int类型的常量,然后压入操作栈栈顶,此时栈顶为100;

9:条件转移指令,依次弹出栈顶两个元素,执行if(第一个元素>第二个元素)条件判断,如果判断结果为true则进行下一步(即第12步),否则转移到第28步。

12:从位置为1的局部变量(即变量i)中取出int类型的值(即0)装载到栈顶,此时栈顶为0;

13:变量1(即x)完成自增操作,即此时x=x+1;

16:把此时栈顶值(即0)存储到变量1中,此时x=0; (注意:此步操作结果实际覆盖掉了变量自增产生的值,正是此步导致了变量x最后的输出为x=0,这也正是有别VC的地方)

17:变量2(即z)完成自增操作,即此时z=z+1;

20:从位置为2的局部变量(即变量z)中取出int类型的值(即1)装载到栈顶,此时栈顶为1;

21:把此时栈顶值存入到变量2(即z)中,此时z=1;

22:变量3(即y)完成自增操作,此时y=y+1;

25:goto跳转到6步,进行循环;

28:得到结果,即为x=0,z=100。

一个能从别人的观念来看事情,能了解别人心灵活动的人,永远不必为自己的前途担心。

黑马程序员——03Java换行符和i=i++的分析

相关文章:

你感兴趣的文章:

标签云: