fix circle check rounded by getType not equals with getClass

This commit is contained in:
金戟 2021-04-23 21:41:30 +08:00
parent a67619d574
commit af409a65a8

View File

@ -43,7 +43,7 @@ public class OmniConstructor {
} }
private static <T> T newInstance(Class<T> clazz, Set<Class<?>> classPool, int level) { private static <T> T newInstance(Class<T> clazz, Set<Class<?>> classPool, int level) {
LogUtil.verbose(level, "creating %s", clazz.getSimpleName()); LogUtil.verbose(level, "Creating %s", clazz.getName());
if (classPool.contains(clazz)) { if (classPool.contains(clazz)) {
return null; return null;
} }
@ -146,10 +146,12 @@ public class OmniConstructor {
try { try {
if (instance.getClass().isArray()) { if (instance.getClass().isArray()) {
for (int i = 0; i < Array.getLength(instance); i++) { for (int i = 0; i < Array.getLength(instance); i++) {
handleCircleReference(Array.get(instance, i), new HashMap<Class<?>, Object>(INITIAL_CAPACITY), ZERO); handleCircleReference(Array.get(instance, i), instance.getClass().getComponentType(),
new HashMap<Class<?>, Object>(INITIAL_CAPACITY), ZERO);
} }
} else { } else {
handleCircleReference(instance, new HashMap<Class<?>, Object>(INITIAL_CAPACITY), ZERO); handleCircleReference(instance, instance.getClass(),
new HashMap<Class<?>, Object>(INITIAL_CAPACITY), ZERO);
} }
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new ClassConstructionException("Failed to access field", e); throw new ClassConstructionException("Failed to access field", e);
@ -157,33 +159,34 @@ public class OmniConstructor {
return instance; return instance;
} }
private static <T> void handleCircleReference(T instance, Map<Class<?>, Object> classPool, int level) private static <T> void handleCircleReference(T instance, Class<?> type, Map<Class<?>, Object> classPool, int level)
throws IllegalAccessException { throws IllegalAccessException {
if (instance == null) { if (instance == null) {
// don't travel null object // don't travel null object
return; return;
} }
LogUtil.verbose(level, "verifying %s", instance.getClass().getSimpleName()); LogUtil.verbose(level, "Verifying %s", type.getName());
classPool.put(instance.getClass(), instance); classPool.put(type, instance);
for (Field f : TypeUtil.getAllFields(instance.getClass())) { for (Field f : TypeUtil.getAllFields(type)) {
f.setAccessible(true); f.setAccessible(true);
Object fieldIns = f.get(instance); Object fieldIns = f.get(instance);
Class<?> fieldType = f.getType(); Class<?> fieldType = f.getType();
if (fieldType.isArray()) { if (fieldType.isArray()) {
if (fieldIns != null) { if (fieldIns != null) {
for (int i = 0; i < Array.getLength(fieldIns); i++) { for (int i = 0; i < Array.getLength(fieldIns); i++) {
handleCircleReference(Array.get(fieldIns, i), classPool, level + 1); handleCircleReference(Array.get(fieldIns, i), fieldType.getComponentType(),
classPool, level + 1);
} }
} }
} else if (!fieldType.isPrimitive() && !TypeUtil.isBasicType(fieldType)) { } else if (!fieldType.isPrimitive() && !TypeUtil.isBasicType(fieldType)) {
if (fieldIns == null && classPool.containsKey(fieldType)) { if (fieldIns == null && classPool.containsKey(fieldType)) {
f.set(instance, classPool.get(fieldType)); f.set(instance, classPool.get(fieldType));
} else if (!classPool.containsKey(fieldType)) { } else if (!classPool.containsKey(fieldType)) {
handleCircleReference(fieldIns, classPool, level + 1); handleCircleReference(fieldIns, fieldType, classPool, level + 1);
} }
} }
} }
classPool.remove(instance.getClass()); classPool.remove(type);
} }
private static Object createInstance(Constructor<?> constructor, Set<Class<?>> classPool, int level) private static Object createInstance(Constructor<?> constructor, Set<Class<?>> classPool, int level)