โดยทั่วไป Variable Handle คือ typed reference ไปยัง variable จะเป็น array element, instance field หรือ static field ของคลาส VarHandle class ให้ write และ read access ตัวแภภายใต้เงื่อนไขเฉพาะ เหล่านี้เป็น immutable และไม่มี visible state ไม่สามารถ sub-class ได้ แต่ละ VarHandle มี generic type T ซึ่งเป็น type ของแต่ละ variable ที่แทน จุดประสงค์ของ VarHandle คือกำหนด standard สำหรับเรียก equivalents ของ java.util.concurrent.atomic และ sun.misc.Unsafe operations บน fields และ array elements
ตัวอย่าง: ใช้ MethodHandles.lookup()
import java.lang.invoke.VarHandle;
import java.lang.invoke.MethodHandles;
public class VarHandleInstanceTest {
public static void main(String args[]) {
try {
VarHandle fieldHandle = MethodHandles.lookup()
.in(Student.class)
.findVarHandle(Student.class, "studentId", int.class);
System.out.println("VarHandle instance created successfully!!!");
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
// Student class
class Student {
protected int studentId;
private String[] marks;
public Student() {
studentId = 0;
marks = new String[] {"75", "85", "95"};
}
}
ผลลัพธ์
VarHandle instance created successfully!!!
คำอธิบาย
MethodHandles.lookup() - ได้ Lookup object สำหรับ caller class
.in(Student.class) - เปลี่ยน lookup context ไปที่ Student class (เข้าถึง protected/private ได้)
.findVarHandle(Student.class, "studentId", int.class) - หา VarHandle สำหรับ instance field
- Parameters: declaring class, field name, field type
VarHandle Factory Methods
| Method |
Use Case |
Parameters |
| findVarHandle |
Instance field |
(declaringClass, fieldName, fieldType) |
| findStaticVarHandle |
Static field |
(declaringClass, fieldName, fieldType) |
| arrayElementVarHandle |
Array elements |
(arrayClass) - e.g., int[].class |
| byteBufferViewVarHandle |
ByteBuffer view |
(byteOrder, fieldType) |
VarHandle Usage Examples
// Instance field access
VarHandle vh = MethodHandles.lookup()
.in(Student.class)
.findVarHandle(Student.class, "studentId", int.class);
Student s = new Student();
vh.get(s); // Read: 0
vh.set(s, 123); // Write
vh.getAndAdd(s, 10); // Atomic add: 123 -> 133
vh.compareAndSet(s, 133, 200); // CAS: true, value=200
// Array access
VarHandle arrVh = MethodHandles.arrayElementVarHandle(int[].class);
int[] arr = new int[10];
arrVh.set(arr, 5, 100); // arr[5] = 100
arrVh.getAndAdd(arr, 5, 50); // arr[5] = 150, returns 100
// Static field access
VarHandle staticVh = MethodHandles.lookup()
.in(MyClass.class)
.findStaticVarHandle(MyClass.class, "count", int.class);
staticVh.get(); // Read static field
staticVh.getAndIncrement(); // Atomic increment
Access Mode Requirements
| Access Mode |
Field Modifier Required |
| Plain |
None |
| Volatile |
volatile |
| Acquire/Release |
volatile |
| Opaque |
volatile |
| Compare-and-Set |
volatile |
ข้อดีของ VarHandle
- Type-safe - generic type parameter
- Standard API - ไม่ต้องใช้ Unsafe
- Flexible - รองรับทุก access modes
- Composable - ทำงานกับ MethodHandles
- JIT optimized - JVM รู้จัก pattern นี้ดี