IT Notes‎ > ‎Java‎ > ‎Java Language‎ > ‎《Java 解惑》笔记‎ > ‎

Puzzle 16: Line Printer

分行符导致的问题

看看下面这段代码:
public class LinePrinter {
        public static void main(String[] args) {
                // Note: \u000A is Unicode representation of linefeed(LF)
                char c = 0x000A;
                System.out.println(c);
        }
}

这里说明一下, Unix-like系统的分行符是LF, 而windows系统中的分行符是CR+LF... … , 你也许还在思考这段代码是否具有平台相关性. 但在NetBeans中, 已经告诉你这段程序无法通过编译. 嗯, 这也是平台独立-- 在任何平台下都不能通过编译. 不过, NetBeans的提示信息是在是让人不知道问题在哪里—机器到底还是笨啊.



前面的Puzzle 14提到Java编译器在解析之前要将Unicode转义字符替换成它所表达的字符. \u000A 被替换成了一个不可见字符–换行符, 以上程序实际上等价于:
public class LinePrinter {
        public static void main(String[] args) {
         // Note:
                is Unicode representation of linefeed(LF)
                char c = 0x000A;
                System.out.println(c);
        }
}
“is Unicode representation of linefeed(LF)” 这段话不是注释, 而成了程序正文的一部分, 当然要报错了.注: 替换Unicode转义字符成相关字符的操作会发生在丢弃空白和换行符之前.

最简单的解决办法就是删掉这句注释了. 另外根据JLS 3.10.6, 000A即是\n的Unicode, 所以以上代码中c可声明为如下形式, 含义更清楚:
  • char c = '\n';
Puzzle 14, 15, 16 讲述了一些关于Unicode转义字符的问题, 这是一个容易引起迷惑之处, 能不用则不用.

其他:平台兼容问题

按照书中P37的说法, 当取消注释之后, 这个程序使能运行了, 但有平台相关的问题. 这个说法需要验证.

代码片段:
char c = 0x000A;
System.out.println("Start");
System.out.println(c);
System.out.println("End");

在windows上运行, 输出:
Start


End
中间是两个空行.

以上是Windows下编译的代码用于Windows平台, 根据编译平题和运行平台的不同,统计上段代码执行之后输出的空行数目如下表:

 纵:编译平台 | 内容:空行数目 | 橫:运行平台
 Windows Ubuntu
 Windows 2 2
 Ubuntu 2 2

注: 假定编译好的代码, 整个目录存放在hello文件夹下, 路径为: hello/book/javapuzzlers/ch03/p16/LinePrinter, 则在控制台下切换到hello目录下, 执行java book.javapuzzlers.ch03.p16.LinePrinter 可查看到运行结果.

TODO 2:
如何打包class文件(制作jar文件), 通过Eclipse较为容易, 通过NetBeans呢? 手工呢?



  1. Puzzle 14: Escape Rout
  2. JLS 3.2 Lexical Translations
  3. JLS 3.4 Line Terminators
ċ
src4p16.tar.gz
(1k)
Iridium Cao,
Jan 16, 2009, 8:47 AM
Comments