使用 Unsafe.putXXX
可以将基元类型放入数组或对象字段中。
但是像下面这样的代码会产生错误。
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(long[].class);
byte[] array = new byte[32];
printArray(array);
varHandle.set(array, 1, 5);
printArray(array);
System.out.println(varHandle.get(array, 1));
}
private static void printArray(byte[] array) {
System.out.println(Arrays.toString(array));
}
}
Exception in thread "main" java.lang.ClassCastException: Cannot cast [B to [J
at java.base/java.lang.Class.cast(Class.java:3780)
at Main.main(Main.java:15)
还有 bytes
可写为:
byte[] array = new byte[32];
long v = 5,
int i = 8;
int high = (int) (v >>> 32);
int low = (int) v;
array[i + 0] = (byte) (high >>> 24);
array[i + 1] = (byte) (high >>> 16);
array[i + 2] = (byte) (high >>> 8);
array[i + 3] = (byte) high;
array[i + 4] = (byte) (low >>> 24);
array[i + 5] = (byte) (low >>> 16);
array[i + 6] = (byte) (low >>> 8);
array[i + 7] = (byte) low;
有没有一种有效的方法来重新解释不同的类型并将它们写入字段和数组 Unsafe
但同样有效。
任何特殊情况下,编译器或jit将识别意图并进行相应的优化。
1条答案
按热度按时间w8ntj3qf1#
为了
byte[]
特别是你可以使用MethodHandles::byteArrayViewVarHandle
:有一些箍你必须跳过与varhandles使他们一样快不安全;
确保varhandle本身是常量,这可以通过将它放入静态final字段并从那里访问它来完成。
确保varhandle调用是准确的。这里这意味着将第二个参数转换为long,因为varhandle也排除了long(在最新的jdk中,您可以使用
VarHandle::withInvokeExactBehavior
执行)。通过在执行强制转换的helper方法中 Package varhandle集和get调用,可以简化这一过程: