Just wanted to point out, that although frowned upon, Java still allows free interpretation/modification of the (typically 4K) memory page under control by the JVM. I.e. if you declare a "uniony type" via an array:
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe $ = (Unsafe) field.get(null);
...one may interpret individual bytes without any bounds check:
long offset = $.arrayBaseOffset(byte[].class);
out.println( $.getByte(a, offset) ); // 1
out.println( $.getByte(a, offset + 1) ); // 2
out.println( $.getByte(a, offset + 2) ); // 3
out.println( $.getByte(a, offset + 3) ); // 4
out.println( $.getByte(a, offset + 4) ); // 5
out.println( $.getByte(a, offset + 5) ); // 6
out.println( $.getByte(a, offset + 6) ); // 7
out.println( $.getByte(a, offset + 7) ); // 8
...or as 4 Bahama shorts:
out.println( $.getShort(a, offset) ); // 513
out.println( $.getShort(a, offset + 2) ); // 1027
out.println( $.getShort(a, offset + 4) ); // 1541
out.println( $.getShort(a, offset + 6) ); // 2055
...or 2 integers:
out.println( $.getInt(a, offset) ); // 67305985
out.println( $.getInt(a, offset + 4) ); // 134678021
...or 1 long:
System.out.println( $.getLong(a, offset) ); // 578437695752307201
So although Sun made it very hard to escape the playpen, it is possible and indeed NIO's DirectByteBuffer etc. takes advantage of this. It's also possible to step beyond a types memory and access memory belonging to another type, although this feels safer to do on the stack than on the heap.