如果自己想学习 JAVA语言规范JAVA SE 8,可以到我的百度云去下载
链接:https://pan.baidu.com/s/18BWrZ4_gLxTyLG5NcwzzJQ
提取码:96wc
这个链接里面 三个资源 都有。
如果想自己扫描版PDF转word,可以参考我的博客 扫描版PDF转可编辑word文档 OCR工具 AbbyyFinereader15百度云资源
当然下面也涉及到一些 编码 的知识,不太了解的同学可以参考一下博客:
关于 ASCII编码
可以查看我的博客 编码标准-ASCII
关于 汉字编码
可以参考我的博客 编码标准-GB2312 GBK GB18030
关于 Unicode
可以参考我的博客 Unicode
JAVA语言规范 JAVA SE 8 - 词法结构
词法结构
程序是用Unicode编写
的,但是Java语言提供了词法翻译
,使得程序可以仅使用ASCII字符,通过Unicode转义字符
来使用任何Unicode字符。 Java定义了行终止符
,用以在现有主机系统的不同使用习惯之间保持行号一致。
在词法翻译
时产生的Unicode字符
将被处理为输入元素的序列
,即空白字符
、注释
和符号
,其中符号
是指句法中的标识符
、关键字
、字面常量
、分隔符
和操作符
。
Unicode
程序是用Unicode字符集编写的,关于这个字符集以及其相关联的字符编码机制的信息 可以在 http://www.unicode.org/ 上找到。
Java SE平台会跟踪Unicode规范的演化。Java的每个发布版本中所使用的Unicode的 准确版本在Character
类的文档中都进行了说明。
Unicode标准最初设计的是16位固定宽度字符的编码机制,后来经过修改,允许表示超过16位的字符。合法的码位范围现在是从U+0000到U +10FFFF,这里使用的是十六 进制“U+n”表示法,其中码位大于U+FFFF的字符被称为补充字符。为了只使用16位的单 元来表示全部码位范围内的字符,Unicode标准定义了一种称为UTF-16的编码机制,其 中补充字符表示成一对16位的码元,第一个码元来自高位代理部分,范围从U+D800到 U+DBFF ;第二个码元来自低位代理部分,范围从U+DC00到U+DFFF。对于从U+0000 到U+FFFF范围内的字符,其码位值和UTF-16码元值是一样的。
Java编程语言的文本是用16位码元序列来表示的,用到的就是UTF-16编码机制。
Java SE平台的某些API,主要是Character类中的API,使用了 32位整数将码位表示成单独的实体。Java SE平台提供了在16位和32位表示之间互相转换的方法。
ASCII ( ANSI X3.4)是用于信息交换的美国标准代码,UTF-16编码机制的前128个字 符就是ASCII字符。
想要了解更多关于 Unicode
的知识 ,可以参考我的博客 Unicode
词法翻译
原始的Unicode字符流会翻译成符号序列
,翻译过程包含了下面三个词法翻译步骤,具体顺序是:
1 )将原始的Unicode字符流中的Unicode转义字符
翻译成相应的Unicode字符
。Unicode转义字符的形式是\uxxxx,其中xxxx是一个十六进制数,转义字符表示的就是编码为xxxx的UTF-16码元
。这个翻译步骤使得任何程序都可以仅由 ASCII字符表示
。
2 )将步骤1产生的Unicode流
翻译成由输入字符
和行终止符
构成的流
。
3)将步骤2产生的由输入字符和行终止符构成的流
翻译成由输入元素构成的序列
,其中空白字符
和注释
被摒弃
。这些输入元素由符号构成
,而后者(符号
)是句法的终结符
。
在翻译的每个步骤都会
采用“最长可能翻译
”这个策略
,即使其翻译的结果最终不能产 生正确的程序,而可能有另一种词法翻译会产生正确程序。但是有一个例外:如果在类型上下文中
进行词法翻译,并且输入流有两个或多个连续的字符>
,后面跟随非> 字符
,那么每个 > 字符都必须翻译为表示数字型比较操作符 > 的符号
。
因此,输入字符 a--b
会被标记为a、-- 和 b
,它们并不能构成任何文法正确的程序,尽管将其标记为a、-、- 和 b
就可以构成文法正确的程序。
如果没有上述有关>字符的规则,那么在类型中的两个连续的>括号,例如 List<List< String>>
,就会被标记为符号右移操作符 >>
,而在List<List<List< String >>>
中的三个连续的〉括号,就会被标记为无符号右移操作符 >>>
。更糟糕的是,对诸如 List<List<List<List< String>>>>
这种连续四个或更多个>括号的标记,会变得具有歧义, 因为各种>
、>>
和 >>>
符号的组合都可以表示成 >>>>
字符序列。
Unicode转义字符
Java编程语言的编译器(Java编译器
)会 首先 识别其输入中的Unicode转义字符
,将 ASCII字符\u及其后面跟着的4位十六进制数
翻译成该十六进制数所表示的UTF-16码元
,而其他字符都保持原样
。补充字符需要用两个连续的Unicode转义字符表示
。 这个翻译步骤将产生Unicode输入字符序列
。
\、U和十六进制数都是ASCII字符
。
对于每一个原始输入字符流中的反斜杠 \
,输入处理还必须从它开始向前检查
,直到碰到第一个非反斜杠字符
或输入流起始位置
,检查的目的是确定在前面紧挨着它连续出现的其他反斜杠 \ 的数量
。
如果该数量是偶数
,那么这个 \
就可以看作是一个Unicode转义字符的开头
;如果该数量是奇数
,那么这个 \
就不能看作是一个 Unicode 转义字符的开头
。
例如,原始输入"\\u2122=\u2122
" 将产生11个字符 “\ \ u 2 1 2 2 = TM
” ( \u2122是字符TM的 Unicode 编码
)。
对于符合条件
但是后面没有u的 \
,会被当作RawInputCharacter
处理,并且成为转义的Unicode流的一部分
。
对于符合条件
并且后面有一个或多个u
的 \
,如果最后一个u的后面没有4位十六进制数
,那么就会产生编译时错误
。
由Unicode转义字符产生的字符不会再参与到之后进行的Unicode转义工作中
。
例如,原始输入流\u005cu005a
会产生6个字符\ u 0 0 5 a
,因为005c是 \ 的 Unicode值
。而所产生的 \ u o o 5 c 不会再产生Unicode值为 005c 的字符 Z
,因为\u005c 产生的\不会被解释成为下一个转义字符的开头
。
Java编程语言规定了一种标准的变换方式
,用于将用Unicode编写的程序变换为ASCII 的形式
,这种方式可以变换程序
的形式,使其能够被基于ASCII的工具处理。这种变换需要将程序源文本中所有的Unicode转义字符转换成后面带有一个额外的u字符的ASCII字符
,例如,\uxxxx
变成\uuxxxx
, 同时会将源文本中的每一个非ASCII字符
,都转换成包含单个u字符的Unicode转义字符
。
这种转换后的版本等价于Java可接受的版本,并且表示的也是完全相同的程序。从这种ASCII形式
还可以恢复
出和原来完全一样的Unicode源程序
,只需将每一个由多个u表示的转义序列转换回少一个u的Unicode字符序列
,同时将每一个只有一个u的转义序列转换回相应的单个Unicode字符
。
当找不到合适的显示字体时,Java编译器应该使用\uxxxx
表示法作为输出格式来显示 Unicode 字符。
行终止符
Java编译器
接下来 会识别行终止符
,将Unicode输入字符序列按行进行划分
。
行
由ASCII字符 CR
,或 LF
,或 CR LF
终止
。两个CR字符后面紧跟一个LF字符会被当作是一个行终止符而不是两个
。
行终止符还可以表示一条//形式的注释的终止
。
由行终止符定义的行可以
用来确定
Java编译器产生的行号
。
按行划分
的结果
是由行终止符
和输入字符
构成的序列
,它们是标记处理过程
中第三步的终结符号
。
输入元素和符号
在转义处理
和之后的输入行识别
中产生的 输入字符和行终止符
会被精简
为输入元素序列
。
不是空白字符
和注释
的输入元素被称为符号
,它们是 句法 的终结符
。
空白字符
和 注释
可以用于分隔符号
,这些符号如果连在一起, 可能会以其他方式标记。例如,输入中的ASCII字符-
和=
只有在它们之间没有任何空白字符或注释的情况下
&