63

投稿日

【ネタ】コメントだけしか書いていないのに「Hello, world!」と表示されるJavaプログラム

これはJavaでポインタで使えるというネタから着想を得たプログラミングネタです。
厳密には 「コメントだけ書いてあるようにしか見えない」 です。

コメントだけしか書いていないのに「Hello, world!」と表示されるJavaプログラム

実行環境
 % java --version
openjdk 16.0.2 2021-07-20
OpenJDK Runtime Environment Microsoft-25298 (build 16.0.2+7)
OpenJDK 64-Bit Server VM Microsoft-25298 (build 16.0.2+7, mixed mode)

「百聞は一見にしかず」なので、まずは見てみましょう。

Main.java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        //\u000a\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0022\u0048\u0065\u006c\u006c\u006f\u002c\u0020\u0077\u006f\u0072\u006c\u0064\u0021\u0022\u0029\u003b
    }
}

シンタックスハイライトだと、main関数の中にはコメントしかないですね。
しかし、実行すると「Hello, world!」と出力されます。

Main.javaの実行
% java Main.java
Hello, world!

種明かし

Javaはコンパイル前に、 ソースコード中のUnicodeエスケープシーケンスをテキストへ変換する。
\u000a は改行なので、 //\u000a で実はコメントが終わっている。
そのため、それより後に書かれたテキストは、プログラムとしてコンパイルされる。
\u0053\u0079... のように、Unicodeエスケープシーケンスでプログラムを書いておけば、コメントの中にプログラムを仕込むことができる。

Unicodeエスケープシーケンスを展開すると、System.out.println("Hello, world!"); となる。

image.png

コンパイラが認識している文字列は以下のようになっている。

Main.java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        //
System.out.println("Hello, world!");
    }
}

シンタックスハイライトにハイライトに騙されるところでしたね。

Javaでポインタが使える

着想の元になった記事の内容です。コードと種明かしだけ掲載しておきます。

*演算子を用いてJavaでポインタを扱う

PointerTest.java
public class PointerTest {
    public static void main(String[] args) {
        int i = 5;
        // #start unsafe# http://java.sun.com\u000a\u002f\u002a
        int *ip = &i;
        // ポインタの内容に3を加算
        *ip += 3;
        // 演算結果をiに代入
        i = *ip;
        // #end unsafe# http://java.sun.com\u002a\u002fi+=\u0033\u003b
        System.out.println(i);
    }
}

種明かし

PointerTest.java
public class PointerTest {
    public static void main(String[] args) {
        int i = 5;
        // #start unsafe# http://java.sun.com
/*
        int *ip = &i;
        // ポインタの内容に3を加算
        *ip += 3;
        // 演算結果をiに代入
        i = *ip;
        // #end unsafe# http://java.sun.com*/i+=3;
        System.out.println(i);
    }
}

本当にコメントだけしか書いていないのに「Hello, world!」と表示されるJavaプログラム

ソースコードに記述されてるすべてのUnicodeエスケープシーケンスが展開されるのなら、
プログラムすべてを、Unicodeエスケープシーケンスで記述しても動作するのではないか?

そこで作ってみた。

Main2.java
//\u000a\u0069\u006d\u0070\u006f\u0072\u0074\u0020\u006a\u0061\u0076\u0061\u002e\u0075\u0074\u0069\u006c\u002e\u002a\u003b\u000a\u000a\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0063\u006c\u0061\u0073\u0073\u0020\u004d\u0061\u0069\u006e\u0032\u0020\u007b\u000a\u0020\u0020\u0020\u0020\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0073\u0074\u0061\u0074\u0069\u0063\u0020\u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u006e\u0028\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u0020\u0061\u0072\u0067\u0073\u0029\u0020\u0074\u0068\u0072\u006f\u0077\u0073\u0020\u0045\u0078\u0063\u0065\u0070\u0074\u0069\u006f\u006e\u0020\u007b\u000a\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0022\u0048\u0065\u006c\u006c\u006f\u002c\u0020\u0077\u006f\u0072\u006c\u0064\u0021\u0022\u0029\u003b\u000a\u0020\u0020\u0020\u0020\u007d\u000a\u007d\u000a
Main2.javaの実行
% java Main2.java
Hello, world!

本当に コメントだけしかないように見える プログラムもしっかり動作した。

その他

最後に

ラインコメント(一行のコメント)に\u000aと記述したら大変なことになりそうです。

新規登録して、もっと便利にQiitaを使ってみよう

  1. あなたにマッチした記事をお届けします
  2. 便利な情報をあとで効率的に読み返せます
ログインすると使える機能について

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
新規登録
すでにアカウントを持っている方はログイン
63