Why does this code, written backwards, print "Hello World!"

Viewed 16710

Here is some code that I found on the Internet:

class M‮{public static void main(String[]a‭){System.out.print(new char[]
{'H','e','l','l','o',' ','W','o','r','l','d','!'});}}    

This code prints Hello World! onto the screen; you can see it run here. I can clearly see public static void main written, but it is backwards. How does this code work? How does this even compile?

Edit: I tried this code in IntellIJ, and it works fine. However, for some reason it doesn't work in notepad++, along with cmd. I still haven't found a solution to that, so if anyone does, comment down below.

5 Answers

Chapter 3 of the language specification provides an explanation by describing in detail how the lexical translation is done for a Java program. What matters most for the question:

Programs are written in Unicode (§3.1), but lexical translations are provided (§3.2) so that Unicode escapes (§3.3) can be used to include any Unicode character using only ASCII characters.

So a program is written in Unicode characters, and the author can escape them using \uxxxx in case the file encoding does not support the Unicode character, in which case it is translated to the appropriate character. One of the Unicode characters present in this case is \u202E. It is not visually shown in the snippet, but if you try switching the encoding of the browser, the hidden characters may appear.

Therefore, the lexical translation results in the class declaration:

class M\u202E{

which means that the class identifier is M\u202E. The specification considers this as a valid identifer:

Identifier:
    IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
IdentifierChars:
    JavaLetter {JavaLetterOrDigit}

A "Java letter-or-digit" is a character for which the method Character.isJavaIdentifierPart(int) returns true.

This is actually because of Unicode bidirectional support.

U+202E RIGHT TO LEFT OVERRIDE
U+202D LEFT TO RIGHT OVERRIDE

So, those are some tricky characters. They are actually defined for right-to-left language support. The real code is

class M<U+202E>{public static void main(String[]a<U+202D>){System.out.print(new char[]
    {'H','e','l','l','o',' ','W','o','r','l','d','!'});}}

(got this by pasting into cmd.exe). Hope this answer helps you find out how this works.

Related