Java руны

Открой Java руны — магические знаки, которые превращают код в легенду и делают твою программу избранной

Если вы ищете в интернете слово «руны» в контексте Java, поисковик может одновременно выдать два совершенно разных результата:

  • обсуждение 32-битного типа rune из языка Go (который действительно представляет Unicode-символ);
  • упоминания о новом биткоин-протоколе Runes для выпуска токенов.

В «чистой» Java ни тот, ни другой термин официально не существует. Однако в русскоязычной среде программистов слово «руны» всё чаще используется как образное обозначение Unicode-кодовых точек, с которыми Java работает напрямую. В этой статье мы разложим всё по полочкам:

  1. Что в Java считается «руной».
  2. Как «руны» преобразуются в цифры и обратно.
  3. Как «руны» пересекаются с потоками (Runnable/Thread).
  4. Как не путать Java-мир с Go и блокчейном.

Java «руна» ≈ Unicode code point

В отличие от Go, где существует тип rune (псевдоним int32), в Java «руной» довольно условно называют 21-битное значение кодовой точки UTF-16/UTF-32. Фактически это просто int, который можно получить из char или String:


String s = "9";
int codePoint = s.codePointAt(0); // 57 (0x39)

Таким образом:

  • char в Java — это 16-битная UTF-16 code unit (иногда одна, иногда пара символов для emoji и прочих «суррогатов»);
  • int (code point) — это то, что в Go официально зовут rune.

Преобразование «руны» в цифру и обратно

Техника, которую часто называют «вычитание нулевой руны», выглядит так:


char digit = '7';
int value = digit ⎯ '0'; // 7

Работает она, потому что в Unicode символы '0'..'9' идут строго последовательно:

Символ (char) Code point
‘0’ 48 (0x30)
‘1’ 49 (0x31)
… …
‘9’ 57 (0x39)

Этот приём универсален и для Java, и для Go, и для любого другого языка, который использует Unicode.

Обратное преобразование

Чтобы получить символ по числовому значению, достаточно:


int value = 5;
char digit = (char) ('0' + value); // '5'

Runnable и «руны» в многопоточности

Иногда новички путают понятия:

  • rune, «руна», Unicode-символ;
  • Runnable — интерфейс в Java для запуска кода в отдельном потоке.

На деле никакой связи между этими словами нет, только созвучие. Пример минимального Runnable:


public class DigitPrinter implements Runnable {
 private final int digit;
 public DigitPrinter(int digit) { this.digit = digit; }

 @Override
 public void run {
 char ch = (char) ('0' + digit); // «руна» → символ
 System.out.println(Thread.currentThread.getName + ": " + ch);
 }
 public static void main(String[] args) {
 for (int i = 0; i < 10; i++) {
 new Thread(new DigitPrinter(i)).start;
 }
 }
}

Каждый поток выводит «свою» цифру, преобразованную из «руны».

Как не попасть в ловушку терминов

Термин Где используется Что реально означает
rune (тип) Go int32, кодовая точка Unicode
Runes (протокол) Биткоин стандарт для выпуска токенов через OP_RETURN
Runnable Java интерфейс для многопоточности
«руна» (жаргон) Русскоязычные Java-чаты code point как int

Мини-шпаргалка

Символ → число:


"5".codePointAt(0) ー '0' → 5

Число → символ:


(char) ('0' + 5) → '5'

Итерация по символам/«рунам»:


String s = "Привет!";
s.codePoints.forEach(cp -> System.out.printf("U+%04X%n", cp));

Java не имеет типа rune, но вы всегда можете оперировать Unicode «рунами» как int. Главное — не путать это с интерфейсом Runnable и криптовалютным протоколом Runes. Запомните: в Java «руна» — это просто кодовая точка, а run — это метод для запуска потока. И всё!