Poniższy kod jest poprawnym programem w języku Java.Co może spowodować błąd kompilatora Java podczas analizowania komentarza?
public class Foo
{
public static void \u006d\u0061\u0069\u006e(String[] args)
{
System.out.println("hello, world");
}
}
Identyfikator main
jest zapisywany przy użyciu sekwencji unikodowych Unicode. Kompiluje i działa dobrze.
$ javac Foo.java && java Foo
hello, world
Chociaż poniższe informacje mogą nie być konieczne do udzielenia tego pytania, udostępniam je na wypadek, gdyby ktoś był ciekawy. Używam kompilatora Java z OpenJDK na Debianie 8.0, ale to, o co pytam w tym pytaniu, powinno dotyczyć dowolnego kompilatora Java.
$ javac -version
javac 1.7.0_79
$ readlink -f $(which javac)
/usr/lib/jvm/java-7-openjdk-amd64/bin/javac
Poniższy program jest błąd, ponieważ sekwencja ucieczki używany do pisania m
z main
jest nieprawidłowy.
public class Foo
{
public static void \u6d\u0061\u0069\u006e(String[] args)
{
System.out.println("hello, world");
}
}
Kompilator narzeka na nielegalną sekwencję Unicode.
$ javac Foo.java && java Foo
Foo.java:3: error: illegal unicode escape
public static void \u6d\u0061\u0069\u006e(String[] args)
^
Foo.java:3: error: invalid method declaration; return type required
public static void \u6d\u0061\u0069\u006e(String[] args)
^
2 error
Co mnie zaskoczyło to, że następujący program jest również nieważny, mimo że nielegalny sekwencja escape Unicode wydaje się pojawiać się w komentarzu.
public class Foo
{
// This comment contains \u6d.
public static void main(String[] args)
{
System.out.println("hello, world");
}
}
Tutaj jest błąd.
$ javac Foo.java && java Foo
Foo.java:3: error: illegal unicode escape
// This comment contains \u6d.
^
1 error
Kompilator uskarża się na nielegalną sekwencję unikodową Unicode, chociaż wydaje się, że jest w komentarzu.
Przyczyna tego zachowania staje się jasna, gdy widzimy, jak definiuje się komentarz końcowy w JLS §3.7.
EndOfLineComment:
// {InputCharacter}
JLS §3.4 określa InputCharacter
następująco.
InputCharacter:
UnicodeInputCharacter but not CR or LF
Wreszcie JLS §3.3 określa UnicodeInputCharacter
następująco.
UnicodeInputCharacter:
UnicodeEscape
RawInputCharacter
UnicodeEscape:
\ UnicodeMarker HexDigit HexDigit HexDigit HexDigit
UnicodeMarker:
u {u}
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
RawInputCharacter:
any Unicode character
Dlatego analizator leksykalny jest wymagane, aby najpierw rozpoznawać sekwencje Unicode w celu rozpoznania komentarze, a jeśli nielegalne sekwencja escape Unicode zostanie znaleziony, analiza leksykalna zawiedzie i błąd będzie występować. Dlatego kompilator nigdy nie przystąpiłby do rozpoznawania komentarza, który zawierał nielegalną sekwencję unikową Unicode.
Chociaż kiedyś myślałem, że od początku komentarza (powiedzmy //
) do końca jest ignorowany, powyższy przykład pokazuje, że tak nie jest, ponieważ analizator leksykalny musi rozpoznawać sekwencje specjalne Unicode między początkiem komentarza i zakończenia komentarza, a nielegalna sekwencja eskejpowa Unicode może spowodować niepowodzenie analizy leksykalnej.
Co jeszcze może spowodować błąd kompilatora podczas analizowania komentarza?
wygląd [tutaj] (http://stackoverflow.com/questions/9225124/error-due-to-content-in-a-legal- comment-in-java) – Dando18
@ Dando18 Dzięki za udostępnienie linku. Jednak żadna z odpowiedzi nie odpowiada na to pytanie. Odpowiedź, która mówi o '@ przestarzałym 'nie jest odtwarzalna w OpenJDK. Odpowiedź, która wspomina o błędzie kompilatora '/ * z powodu tego znaku Unicode '* /' * /' jest niepoprawna, ponieważ końcowe "* /" wyraźnie nie znajduje się w komentarzu. Pozostałe dwie odpowiedzi nie odnoszą się do konkretnego pytania, które zadano. –
http://stackoverflow.com/q/30727515/2158288 – ZhongYu