V tomto krátkém článku si ukážeme, že i v Javě (přesněji Sun JDK) můžeme používat ukazatelovou aritmetiku. Nehledejte v tom však něco praktického. Jde spíše o exkurzi do méně známých končin JDK.

Celé kouzlo je schováno ve tříde sun.misc.Unsafe. Tato třída umožňuje např. přímý přístup do paměti, atomické operace s pamětí (Compare and Swap), kopírování obsahu paměti, zamykání objektů a "parkování" vláken.

Třída sun.misc.Unsafe má pouze privátní konstruktor, takže její instanci nelze vytvořit přímo. Získáme ji ze statického atributu theUnsafe této třídy pomocí reflection (metoda getUnsafe). Dále naalokujeme paměť (metoda allocateMemory) a s použitím ukazatelové aritmetiky do této paměti zapíšeme (metoda writeToMem). Nakonec obsah paměti zobrazíme (metoda printMem).

import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class PF2010 {

public static void main(String[] args) {
byte[] magic = {80, 70, 32, 50, 48, 49, 48, 33};
try {
Unsafe u = getUnsafe();
int len = magic.length * 2;
long adr = u.allocateMemory(len);
writeToMem(u, adr, magic);
printMem(u, adr, len);
} catch (Exception e) {
e.printStackTrace();
}
}

static Unsafe getUnsafe() throws Exception {
Class c = Unsafe.class;
Field f = c.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(null);
}

static void writeToMem(Unsafe u, long p, byte[] values) {
for (byte b : values) {
u.putChar(p, (char) b);
p += 2;
}
}

static void printMem(Unsafe u, long p, int len) {
int n = len / 2;
for (; n > 0; n--) {
char c = u.getChar(p);
System.out.print(c);
p += 2;
}
System.out.println();
}
}