Как создать varhandle для доступа к элементам массива в Java 9+ - PullRequest
0 голосов
/ 25 октября 2018

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

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

Я вижу, что MethodHandle имеетarrayElementVarHandle(int[].class), который возвращает VarHandle.Может быть, мне нужно каким-то образом преобразовать VarHandle обратно в MethodHandle и затем вызвать arrayElementVarHandle(), чтобы это можно было сделать?

1 Ответ

0 голосов
/ 25 октября 2018

Я не знаком с API invoke, поэтому ответьте на этот вопрос с небольшим количеством соли, но почему вы не можете просто использовать 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
...