Java语言规范第三章-词法(Java Language Specification – Chapter3 Lexical)
UnicodeInputCharacter:
UnicodeEscape
RawInputCharacter
UnicodeEscape:
/ UnicodeMarker HexDigit HexDigit HexDigit HexDigit
UnicodeMarker:
u
UnicodeMarker u
RawInputCharacter:
any Unicode character
HexDigit: one of
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
必须计算有多少个连续的/,与非/或者输入流的起始相分隔,如果连续的/的个数为奇数,那么/作为Unicode的转义字符,否则不作为Unicode的转义字符。例如"//u2297=/u2297"的输出为"//u2297= " (/u2297的Unicode编码字符为" ")。
如果合法(连续的奇数个/)的Unicode转义字符后面的字符不是u,那么作为原始字符来处理。如果后面的字符是1个或者多个u,而且字符u后面不是四位16进制数,那么将发生编译时错误。
进行Unicode转义时,并不进行二次转义。例如原始输入/u005cu005a转义后的输出为/u005a,虽然/005c是Unicode字符/,而/u005a是字符Z,但是Unicode转义时不进行二次转义。
LineTerminator:
the ASCII LF character, also known as "newline"
the ASCII CR character, also known as "return"
the ASCII CR character followed by the ASCII LF character
InputCharacter:
UnicodeInputCharacter but not CR or LF
行结束符为ASCII中的CR,LF以及CR LF。CR后面紧跟LF被作为一个行结束符,而不是两个。
Input:
InputElementsopt Subopt
InputElements:
InputElement
InputElements InputElement
InputElement:
WhiteSpace
Comment
Token
Token:
Identifier
Keyword
Literal
Separator
Operator
Sub:
the ASCII SUB character, also known as "control-Z"
为了兼容某些特定的系统,作为一个特例情况,ASCII的SUB字符(/u001a或者CTRL+Z)如果出现在输入流的末尾,那么该字符被忽略。
WhiteSpace:
the ASCII SP character, also known as "space"
the ASCII HT character, also known as "horizontal tab"
the ASCII FF character, also known as "form feed"
LineTerminator
Identifier:
IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
IdentifierChars:
JavaLetter
IdentifierChars JavaLetterOrDigit
JavaLetter:
any Unicode character that is a Java letter (see below)
JavaLetterOrDigit:
any Unicode character that is a Java letter-or-digit (see below)
两个标识符相同当且仅当它们的每个字符都具有相同的Unicode字符。
两个具有相同表现形式可能是不同的。例如下面的这些标识符是不同的。
LATIN CAPITAL LETTER A (A, /u0041)
LATIN SMALL LETTER A (a, /u0061)
GREEK CAPITAL LETTER ALPHA (A, /u0391)
CYRILLIC SMALL LETTER A (a, /u0430)
MATHEMATICAL BOLD ITALIC SMALL A (a, /ud835/udc82)
Unicode组合字符与分解后的字符是不同的。例如当进行排序时,LATIN CAPITAL LETTER A ACUTE (Á, /u00c1)可以被认为是LATIN CAPITAL LETTER A (A, /u0041)后面紧跟着NON-SPACING ACUTE (´, /u0301)组成的,但是他们是不同的标识符。
CharacterLiteral:
' SingleCharacter '
' EscapeSequence '
SingleCharacter:
InputCharacter but not ' or /
字符CR和LF不再属于InputCharacter;因为它们在之前的阶段已经被认为是LineTerminator。
如果SingleCharacter或者EscapeSequence后面跟的字符不是单引号(’)的话,将导致编译时错误。
如果行结束符出现在起始单引号和结束单引号之间,将导致编译时错误。
由于Unicode转义已经在之前的阶段中被处理,所以下面的字符是不正确的/u000a(LF),/u000d(CR),因为他们在Unicode转义阶段被转义为实际的linefeed以及carriage return,而在行结束符阶段被看作是行结束符号。所以应该使用/n和/r来替代。
StringLiteral:
" StringCharactersopt "
StringCharacters:
StringCharacter
StringCharacters StringCharacter
StringCharacter:
InputCharacter but not " or /
EscapeSequence
字符CR和LF不再属于InputCharacter;因为它们在之前的阶段已经被认为是LineTerminator。
如果SingleCharacter或者EscapeSequence后面跟的字符不是单引号(’)的话,将导致编译时错误。
如果行结束符出现在起始单引号和结束单引号之间,将导致编译时错误。
由于Unicode转义已经在之前的阶段中被处理,所以下面的字符是不正确的/u000a(LF),/u000d(CR),因为他们在Unicode转义阶段被转义为实际的linefeed以及carriage return,而在行结束符阶段被看作是行结束符号。所以应该使用/n和/r来替代。
package org.jff.jls.ch2;
public class StringIntern {
public static void main(String[] args) {
String hello = "Hello", lo = "lo";
System.out.print((hello == "Hello") + " ");//true
System.out.print((Other.HELLO == hello) + " ");//true
System.out.print((org.jff.jls.ch2.other.Other.HELLO == hello) + " ");//true
System.out.print((hello == ("Hel" + "lo")) + " ");//true
System.out.print((hello == ("Hel" + lo)) + " ");//false
System.out.println(hello == ("Hel" + lo).intern());//true
}
}
package org.jff.jls.ch2.other;
public class Other {
public static String HELLO = "Hello";
}
常量表达式计算出来的字符串发生在编译时,因此作为字符串处理。
通过连接计算出来的字符串发生在运行时,作为新建的对象,因此是不相同的。
本文详细介绍了Java语言规范中的词法部分,包括Unicode输入字符、行结束符、输入元素、空白字符、标识符等概念及其定义。同时展示了如何处理Unicode转义序列及字符和字符串字面量。
298

被折叠的 条评论
为什么被折叠?



