Вместе с jdk12 появились шахматные символы (источник):
Unicode 11.0.0 introduced the following new features that are now included in JDK 12
[...] 4 blocks for the following existing scripts:
Georgian Extended
Mayan Numerals
ndic Siyaq Numbers
Chess Symbols
Имея это в виду, я попытался напечатать эти символы с помощью следующего кода, чтобы проверить функциональность и использовать их позже в небольшой игре в шахматы:
Character.UnicodeBlock block = Character.UnicodeBlock.CHESS_SYMBOLS;
for (int i = 0; i < 1114112; i++) {
char unicode = (char) i;
if (Character.UnicodeBlock.of(unicode) == block) {
System.out.println(unicode);
}
}
Однако ничего не печатает. Код работает, если я заменю CHESS_SYMBOLS, например, на ARABIC. У меня джава 12.0.1.
Вопрос: Почему приведенный выше код ничего не печатает?
@StephenC Я использую Intellij, если я попытаюсь System.out.println("♔");, он напечатает символ, поэтому я считаю, что это строго связано с кодом.
@SteveSmith Он не печатает прямоугольники, он вообще ничего не печатает. Также я хотел бы использовать UniblockCode для печати или, по крайней мере, понять, почему это не работает.
Вы проверяете только первые 65536 символов, из них 1 114 112 символов Unicode.
@JGNI Я отредактировал код, но все еще не печатаю. Я тоже пробовал Character.MAX_VALUE.
Вы установили кодировку на UTF-8?
@SteveSmith Если System.out.println("♔"); работает, то это не должно быть проблемой с кодировкой, или, может быть, что-то нужно указать в коде?
Может быть, кодировка Windows не содержит всех символов Юникода? coderanch.com/t/538165/java/Отображение символов UniCode




Некоторые символы шахматных символов существуют в блоке «Разные символы», но вы специально проверяете 16-битные значения char в другом блоке. Блок Chess Symbols содержит символы нуль с 16-битными значениями; он начинается с U+1FA00 и заканчивается с U+1FA6F.
Выполняя приведение к char, вы обрезаете все значения выше U+FFFF до младших 16 бит; например, если i равно 0x1fa60, приведение его к char сделает его 0xfa60, что предотвратит успешную проверку блока.
Чтобы ваш код работал, вам нужно перестать предполагать, что все кодовые точки являются 16-битными значениями. Вы можете сделать это, изменив это:
char unicode = (char) i;
к этому:
int unicode = i;
Конечно, при замене char unicode = (char) i; на int unicode = i; вообще не нужны две разные переменные.
К сожалению, у Character.UnicodeBlock нет методов, чтобы определить начальное и конечное значение для кодовых точек в блоке. В Unicode 11 блок шахматных символов начинается от U+1FA00 до U+1FA6D.
Java использует UTF-16 и суррогатные пары для представления символов более U+10000. В этом случае кодовая точка U+1FA00 будет представлена двумя значениями char: U+D83E (старший суррогат) и U+DE60 (младший суррогат).
Вы должны использовать Character.toChars(), чтобы правильно напечатать кодовую точку, которая всегда является int:
Character.UnicodeBlock block = Character.UnicodeBlock.CHESS_SYMBOLS;
for (int i = 0; i < 1114112; i++) {
if (Character.UnicodeBlock.of(i).equals(block)) {
System.out.println(Character.toChars(i));
}
}