Skip to content

Instantly share code, notes, and snippets.

@lukaseder
Created August 25, 2020 09:10
Show Gist options
  • Save lukaseder/1bc2ea085a36d275b7e2df3f1ab1ce17 to your computer and use it in GitHub Desktop.
Save lukaseder/1bc2ea085a36d275b7e2df3f1ab1ce17 to your computer and use it in GitHub Desktop.
ListSurprise.java
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import sun.misc.Unsafe;
public class ListSurprise {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
Collections.addAll(numbers, 3, 1, 4, 1, 5, 5, 9);
Iterator<Integer> it = numbers.iterator();
System.out.print(it.next());
System.out.print('.');
System.out.print(it.next());
System.out.print(it.next());
System.out.print(it.next());
System.out.print(it.next());
doSomething(numbers);
System.out.print(it.next());
if (!numbers.equals(List.of(3,1,4,1,5,9)))
throw new AssertionError();
}
private static void doSomething(List<Integer> numbers) {
try {
// Don't log anything fancy https://stackoverflow.com/a/46458447/521799
System.setErr(new PrintStream(new ByteArrayOutputStream()));
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe u = (Unsafe) theUnsafe.get(null);
Class<?> cls = Class.forName("jdk.internal.module.IllegalAccessLogger");
Field logger = cls.getDeclaredField("logger");
u.putObjectVolatile(cls, u.staticFieldOffset(logger), null);
// From now on, 5 is 9
Class<?> integerCacheClass = Class.forName("java.lang.Integer$IntegerCache");
Field integerCacheField = integerCacheClass.getDeclaredField("cache");
Field integerValue = Integer.class.getDeclaredField("value");
integerCacheField.setAccessible(true);
integerValue.setAccessible(true);
Object[] integerCache = (Object[]) integerCacheField.get(Integer.class);
int modifiers = integerValue.getModifiers();
Field modifiersField = integerValue.getClass().getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiers = modifiers & ~Modifier.FINAL;
modifiersField.setInt(integerValue, modifiers);
integerValue.set(integerCache[133], 9);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment