Berikut ini beberapa kode yang saya temukan di Internet:
class M{public static void main(String[]a){System.out.print(new char[]
{'H','e','l','l','o',' ','W','o','r','l','d','!'});}}
Kode ini dicetak Hello World!
di layar; Anda dapat melihatnya berjalan di sini . Saya bisa melihat public static void main
tulisan dengan jelas , tetapi terbalik. Bagaimana cara kerja kode ini? Bagaimana ini bisa dikompilasi?
Sunting: Saya mencoba kode ini di IntellIJ, dan berfungsi dengan baik. Namun, untuk beberapa alasan itu tidak berfungsi di notepad ++, bersama dengan cmd. Saya masih belum menemukan solusi untuk itu, jadi jika ada yang melakukannya, komentar di bawah.
java
unicode
right-to-left
Labu Imajiner
sumber
sumber
M
dan juga setelah[]a
: fileformat.info/info/unicode/char/202d/index.htm Ini disebut LEFT-TO-RIGHT OVERRIDEniam diov citats cilbup
Kedengarannya seperti pepatah Latin ..Jawaban:
Ada karakter yang tidak terlihat di sini yang mengubah cara kode ditampilkan. Di Intellij, ini dapat ditemukan dengan menyalin-menempelkan kode ke string kosong (
""
), yang menggantikannya dengan Unicode lolos, menghapus efeknya dan mengungkapkan urutan yang dilihat kompilator.Ini adalah output dari copy-paste itu:
Karakter kode sumber disimpan dalam urutan ini, dan kompilator memperlakukannya sebagai urutan ini, tetapi mereka ditampilkan secara berbeda.
Perhatikan
\u202E
karakter, yang merupakan override kanan ke kiri, memulai blok di mana semua karakter dipaksa untuk ditampilkan kanan-ke-kiri, dan\u202D
, yang merupakan override kiri-ke-kanan, memulai blok bersarang di mana semua karakter dipaksa ke kiri-ke-kanan, mengesampingkan penimpaan pertama.Ergo, ketika menampilkan kode asli,
class M
ditampilkan secara normal, tetapi\u202E
membalikkan urutan tampilan segala sesuatu dari sana ke\u202D
, yang membalikkan semuanya lagi. (Secara formal, segala sesuatu dari\u202D
ke terminator garis akan terbalik dua kali, sekali karena\u202D
dan sekali dengan sisa teks terbalik karena\u202E
, itulah sebabnya teks ini muncul di tengah-tengah baris, bukan di akhir.) Arah baris berikutnya ditangani secara independen dari yang pertama karena terminator garis, sehingga{'H','e','l','l','o',' ','W','o','r','l','d','!'});}}
ditampilkan secara normal.Untuk algoritme dua arah Unicode penuh (sangat rumit, lusinan halaman), lihat Unicode Standard Annex # 9 .
sumber
Itu terlihat berbeda karena Algoritma Bidirectional Unicode . Ada dua karakter RLO dan LRO yang tidak terlihat yang digunakan Unicode Bidirectional Algorithm untuk mengubah tampilan visual dari karakter-karakter yang bersarang di antara dua metacharacters ini.
Hasilnya secara visual mereka terlihat dalam urutan terbalik, tetapi karakter sebenarnya dalam memori tidak terbalik. Anda dapat menganalisis hasilnya di sini . Kompiler Java akan mengabaikan RLO dan LRO, dan memperlakukannya sebagai spasi putih yang karenanya kode dikompilasi.
Catatan 1: Algoritma ini digunakan oleh editor teks dan browser untuk secara visual menampilkan karakter baik karakter LTR (Bahasa Inggris) dan karakter RTL (mis. Bahasa Arab, Bahasa Ibrani) bersamaan pada saat yang bersamaan - karenanya "bi" -directional. Anda dapat membaca lebih lanjut tentang Algoritma Bidirectional di situs web Unicode .
Catatan 2: Perilaku yang tepat dari LRO dan RLO didefinisikan dalam Bagian 2.2 dari Algoritma.
sumber
M\u202E
dana\u202D
, tetapi pengidentifikasi tersebut tampaknya diperlakukan setara denganM
dana
. (JLS tidak melakukan pekerjaan dengan baik untuk menjelaskan hal ini.)Karakter
U+202E
mencerminkan kode dari kanan ke kiri, itu sangat pintar. Tersembunyi mulai di M,Ya, pada awalnya ketika saya melihat pertanyaan saya tegar, "ini semacam lelucon, kehilangan waktu orang lain", tetapi kemudian, saya membuka IDE saya ("IntelliJ"), membuat kelas, dan melewati kode ... dan itu dikompilasi !!! Jadi, saya melihat lebih baik dan melihat bahwa "kekosongan publik statis" mundur, jadi saya pergi ke sana dengan kursor, dan menghapus beberapa karakter ... Dan apa yang terjadi? Karakternya mulai terhapus ke belakang , jadi, saya pikir mmm .... jarang ... Saya harus menjalankannya ... Jadi saya melanjutkan untuk menjalankan program, tetapi pertama-tama saya harus menyimpannya ... dan saat itulah saya menemukannya! . Saya tidak dapat menyimpan file karena IDE saya mengatakan bahwa ada pengkodean yang berbeda untuk beberapa karakter, dan tunjukkan di mana itu, Jadi saya memulai penelitian di Google untuk karakter khusus yang dapat melakukan pekerjaan, dan hanya itu :)
Algoritma Bidirectional Unicode, dan yang
U+202E
terlibat, menjelaskan secara singkat :Mengapa membuat beberapa algoritma seperti ini ?
sumber
Bab 3 dari spesifikasi bahasa memberikan penjelasan dengan menjelaskan secara terperinci bagaimana terjemahan leksikal dilakukan untuk program Java. Yang paling penting untuk pertanyaan:
Jadi suatu program ditulis dalam karakter Unicode, dan penulis dapat melarikan diri mereka menggunakan
\uxxxx
dalam kasus pengkodean file tidak mendukung karakter Unicode, dalam hal ini diterjemahkan ke karakter yang sesuai. Salah satu karakter Unicode yang ada dalam kasus ini adalah\u202E
. Ini tidak ditampilkan secara visual dalam cuplikan, tetapi jika Anda mencoba mengalihkan penyandian browser, karakter yang tersembunyi mungkin muncul.Oleh karena itu, terjemahan leksikal menghasilkan deklarasi kelas:
yang berarti bahwa pengidentifikasi kelas adalah
M\u202E
. The spesifikasi menganggap ini sebagai Pengidentifikasi valid:sumber