mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 18:48:20 +08:00
测试Unsafe包操作
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
package config;
|
||||||
|
|
||||||
|
import config.offset.FieldOffset;
|
||||||
|
import config.offset.OffsetUtil;
|
||||||
|
import config.source.ComplexConfiguration;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OffsetTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
|
||||||
|
List<FieldOffset> fieldOffsets = OffsetUtil.getClassMemberOffset(ComplexConfiguration.class);
|
||||||
|
|
||||||
|
output(fieldOffsets);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void output(List<FieldOffset> fieldOffsets) {
|
||||||
|
for (FieldOffset fieldOffset : fieldOffsets) {
|
||||||
|
System.out.println(fieldOffset.getOffsetValue() + " -> " + fieldOffset.getField().getName());
|
||||||
|
if (!fieldOffset.getSubFieldOffsetList().isEmpty()) {
|
||||||
|
output(fieldOffset.getSubFieldOffsetList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package config.offset;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Chris2018998
|
||||||
|
*/
|
||||||
|
public class FieldOffset implements Comparable<FieldOffset> {
|
||||||
|
private final Field field;
|
||||||
|
private Long offsetValue;
|
||||||
|
private List<FieldOffset> subFieldOffsetList;
|
||||||
|
|
||||||
|
public FieldOffset(Field field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getOffsetValue() {
|
||||||
|
return offsetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOffsetValue(Long offsetValue) {
|
||||||
|
this.offsetValue = offsetValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (subFieldOffsetList == null)
|
||||||
|
return field.getName();
|
||||||
|
else {
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("[");
|
||||||
|
|
||||||
|
for (int i = 0; i < subFieldOffsetList.size(); i++) {
|
||||||
|
FieldOffset offset = subFieldOffsetList.get(i);
|
||||||
|
if (i > 0) builder.append(",");
|
||||||
|
builder.append(field.getName()).append(".").append(offset.toString());
|
||||||
|
}
|
||||||
|
builder.append("]");
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<FieldOffset> getSubFieldOffsetList() {
|
||||||
|
return subFieldOffsetList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubFieldOffsetList(List<FieldOffset> subFieldOffsetList) {
|
||||||
|
this.subFieldOffsetList = subFieldOffsetList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Field getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NotNull FieldOffset that) {
|
||||||
|
return this.offsetValue.compareTo(that.offsetValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package config.offset;
|
||||||
|
|
||||||
|
import jdk.internal.misc.Unsafe;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Chris2018998
|
||||||
|
*/
|
||||||
|
public class OffsetUtil {
|
||||||
|
private static Unsafe unsafe;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
unsafe = AccessController.doPrivileged((PrivilegedExceptionAction<Unsafe>) () -> {
|
||||||
|
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
|
theUnsafe.setAccessible(true);
|
||||||
|
return (Unsafe) theUnsafe.get(null);
|
||||||
|
});
|
||||||
|
} catch (Throwable e) {
|
||||||
|
System.err.println("Unable to load unsafe");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<FieldOffset> getClassMemberOffset(Class<?> beanClass) {
|
||||||
|
List<FieldOffset> offsetsList = new LinkedList<>();
|
||||||
|
for (Field field : beanClass.getDeclaredFields()) {
|
||||||
|
FieldOffset fieldOffset = new FieldOffset(field);
|
||||||
|
offsetsList.add(fieldOffset);
|
||||||
|
if (Modifier.isStatic(field.getModifiers()))
|
||||||
|
fieldOffset.setOffsetValue(unsafe.staticFieldOffset(field));
|
||||||
|
else
|
||||||
|
fieldOffset.setOffsetValue(unsafe.objectFieldOffset(field));
|
||||||
|
Class<?> fieldType = field.getType();
|
||||||
|
if (!fieldType.getName().startsWith("java")) {
|
||||||
|
Field[] subfields = fieldType.getDeclaredFields();
|
||||||
|
if (subfields.length > 0) {
|
||||||
|
fieldOffset.setSubFieldOffsetList(getClassMemberOffset(fieldType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(offsetsList);
|
||||||
|
return offsetsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user