Я пытаюсь преобразовать код, который использует Unsafe для доступа к памяти локальных переменных в классах, и код также, кажется, использует Unsafe для доступа к элементам в массиве.
У меня есть следующий код для создания VarHandle для отдельных элементов, и, похоже, он работает.
// where self is a class object, and VarName is the name of the class member
return MethodHandles.privateLookupIn(self, MethodHandles.lookup()).
findVarHandle(self, varName, self);
Я также читал, что вы также можете использовать VarHandles для доступа к элементам массива. Используя приведенный выше код, я могу получить ссылку на весь массив, но я не могу понять, как построить VarHandle, чтобы я мог использовать его для доступа к элементам массива.
Я вижу, что у MethodHandle есть arrayElementVarHandle(int[].class), который возвращает VarHandle. Может быть, мне нужно как-то преобразовать VarHandle обратно в MethodHandle, а затем вызвать arrayElementVarHandle(), чтобы это сделать?




Я не знаком с API вызова, поэтому отнеситесь к этому ответу с недоверием, но почему вы не можете просто использовать VarHandle, возвращенный MethodHandles.arrayElementVarHandle? Чтобы получить доступ к элементам, выполните следующие действия:
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
VarHandle varHandle = MethodHandles.arrayElementVarHandle(int[].class);
int[] array = new int[5];
printArray(array);
varHandle.set(array, 2, 5);
printArray(array);
System.out.println(varHandle.get(array, 2));
}
private static void printArray(int[] array) {
System.out.println(Arrays.toString(array));
}
}
Выход:
[0, 0, 0, 0, 0]
[0, 0, 5, 0, 0]
5
Боже, как ужасен этот API ... Я бы никогда не понял этого, просто проверив сигнатуры методов ...
Я думаю, ты что-то понял. Я был так увлечен механизмом поиска, который привязывал VarHandle к значению, которое я ожидал привязать к массиву напрямую, вместо того, чтобы просто передавать переменную-член в VarHandle. Проверим это.