1
mirror of https://github.com/CarmJos/EasyConfiguration.git synced 2024-09-19 20:25:51 +00:00

测试Unsafe包操作

This commit is contained in:
Carm Jos 2022-04-19 21:43:49 +08:00
parent 0d10a06547
commit 80747ac922
3 changed files with 148 additions and 0 deletions

View File

@ -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());
}
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}