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


------------ android培训 java培训 、期待与您交流!------------
 
1, “回车”( Return )和“换行”(Newl ine

/**
获取当前系统的换行符
 注意:
1,在将流写入文件时,换行应根据操作系统的不同来决定。
2,在程序中我们应 尽量使用System.getProperty("line.separator")来获取当前系统的换行符,而不是写\r\n或\n。
3,当我们在java控制台输出的时候,\r\n和\n都能达到换行的效果。
*/
class LineSeparator{
    public static void main(String[] args) {
        if(System.getProperty("line.separator").equals("\r\n"))  {
                    System.out.println("\\r\\n is for windows");
         } else if(System.getProperty("line.separator").equals("\r")) {
                    System.out.println("\\r is for Mac");
         } elseif(System.getProperty("line.separator").equals("\n")) {
                    System.out.println("\\n is for Unix/Linux");
         }
        System.out.println("aa\nbb");//\n即为换行。
        System.out.println("aaa\rbb");//特别注意输出为:bba 因为\r是回车,即光标返回本行首开始打印。
        System.out.println("aa\r\nbb");//\r\n即为windows系统按下Enter键的操作,分两步,先回车后换行.
    }
}
  '\r'是回车, '\n'是换行,前者使光标到行首,后者使光标下移一格。回车和换行是两回事。通常用的 Enter是两个加起来。 Unix系统里,每行结尾只有 “<换行 >”,即 “\n”Windows系统里面,每行结尾是 <回 车><换行>”,即“\r\n”;Mac系统里,每行结尾是“<回车>”即“\r”。这样导致的直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。

由以上分析可知,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,
Javai=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的实际运行过程。

黑马程序员——03Java换行符和i=i++的分析_第1张图片
解释上图反编译出来的字节码指令内容:

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。 


------------ android培训 java培训 、期待与您交流!------------

详情请查看: http://edu.csdn.net/heima  


你可能感兴趣的:(黑马程序员,黑马程序员,Java,换行符,i++,xuefei)