Javaは識別子にUnicode文字が使えるよってお話

概要

半年前から先輩の誘いでJava講習の非常勤講師を”ときどき”やっている. そしてその講習会の特に初心者向けでは, 意外な質問が飛んできたり受講者分のエラーコードが見られたりするので, 結構楽しい.
そこで今回は質問の中で「ああそういえば」となった事を書き残す. それはJavaで識別子にUnicode文字が使えるよって(まぁ言語仕様の)お話.

言語規定 - 識別子

Javaでは文字リテラルや文字列リテラル, 識別子(クラス, メソッド, 変数名)にUnicode文字を使うことができる. それらはUTF-8, UTF-16で書くもよし, エスケープ記法で書くもよし.
下記例は識別子をUTF-8で書いた場合のプログラムである. これをExample.javaとして保存し, コンパイルしてから実行すればちくわと最も相性のいい”きゅうり”を表示する!…はず!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Example {
static class ちくわについて {
String これでしょ;

void に合うものは (String 相性) {
これでしょ = 相性;
}

String に合うもの(){
return これでしょ;
}
}

public static void main (String[] args){
ちくわについて ちくわ = new ちくわについて();
ちくわ.に合うものは("きゅうり");

System.out.println(ちくわ.に合うもの());
}
}

上記例で示したことはJavaの言語規定にしっかりと記されている(Java言語規定 - 3.8識別子).

おまけ

これを応用?した面白い例を紹介します.

1
2
3
4
5
6
7
8
9
10
11
\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020\u0020
\u0063\u006c\u0061\u0073\u0073\u0020\u0055\u0067\u006c\u0079
\u007b\u0070\u0075\u0062\u006c\u0069\u0063\u0020\u0020\u0020
\u0020\u0020\u0020\u0020\u0073\u0074\u0061\u0074\u0069\u0063
\u0076\u006f\u0069\u0064\u0020\u006d\u0061\u0069\u006e\u0028
\u0053\u0074\u0072\u0069\u006e\u0067\u005b\u005d\u0020\u0020
\u0020\u0020\u0020\u0020\u0061\u0072\u0067\u0073\u0029\u007b
\u0053\u0079\u0073\u0074\u0065\u006d\u002e\u006f\u0075\u0074
\u002e\u0070\u0072\u0069\u006e\u0074\u006c\u006e\u0028\u0020
\u0022\u0048\u0065\u006c\u006c\u006f\u0020\u0077\u0022\u002b
\u0022\u006f\u0072\u006c\u0064\u0022\u0029\u003b\u007d\u007d

!?
!?!?
自分はUnicodeマスターではないため分かりませんでしたが, 実行すると”Hello world”と表示します. これはUgly.javaとして保存すればちゃんと扱えるプログラムなのです.
下記は実際にこれをマルチバイト文字に変換したものです.

1
2
3
4
5
public class Ugly {
public static void main (String[] args) {
System.out.println("Hello w" + "orld");
}
}

ちなみに, このおまけはJava PuzzlersというJavaの問題集に載っています. 難しいけどオススメです.