319
104

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Posted at

これは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と記述したら大変なことになりそうです。

319
104
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
319
104

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?