views:

46

answers:

3

Why does this compile in java 6 (Sun 1.6.0_16):

System.out.println("\u000B");

... but not this:

System.out.println("\u000A");

On this program:

public class Test {
  public static void main(String argv[]) {
  System.out.println("\u000A");
  }
}

I get a

Test.java:3: unclosed string literal
System.out.println("\u000A");

What's going on here?

+6  A: 

The problem is that the Unicode replacement is done very early in compilation. Unicode escapes aren't just valid in strings and character literals (as other escape sequences such as \t are) - they're valid anywhere in code. They're described in a different area of the spec - section 3.3 rather than section 3.10.6; only the latter is about character and string literal escape sequences.

Basically, read section 3 of the spec for more details on lexical structure :)

So your code was actually equivalent to:

public class Test {
  public static void main(String argv[]) {
  System.out.println("
");
  }
}

... which clearly isn't valid code. For carriage return and line feed, basically it's best to use the "\r" and "\n" escape sequences.

Personally I view this handling of Unicode escaping as a flaw in Java, but there's not a lot we can do about it now :(

Jon Skeet
Somebody could put up video tutorial serial like Khan Academy based on Jon Skeet's answers. Respect.
Boris Pavlović
thanks very much !
cartoonfox
+4  A: 

Unicode escapes are expanded prior to lexical analysis. The fact that the Unicode escape appears within a string literal is irrelevant. See JLS 3.2.

org.life.java
+1  A: 

it's because \u000a = \n and the compiler process the java source in order to convert it into tokens, so you cannot use that unicode character in your code. The same for \u000d=\r

punkers