Как создать дескриптор переменной для доступа к элементам массива в Java 9+

Я пытаюсь преобразовать код, который использует 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(), чтобы это сделать?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
694
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я не знаком с 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

Я думаю, ты что-то понял. Я был так увлечен механизмом поиска, который привязывал VarHandle к значению, которое я ожидал привязать к массиву напрямую, вместо того, чтобы просто передавать переменную-член в VarHandle. Проверим это.

Bill 25.10.2018 04:04

Боже, как ужасен этот API ... Я бы никогда не понял этого, просто проверив сигнатуры методов ...

devoured elysium 26.07.2021 05:12

Другие вопросы по теме