This is an automated email from the ASF dual-hosted git repository.

chaokunyang pushed a commit to branch releases-0.12
in repository https://gitbox.apache.org/repos/asf/fory.git

commit 6f3d06b517ed5b149e190d6ab489e381ce2b4bd7
Author: chaokunyang <[email protected]>
AuthorDate: Sat Sep 20 00:27:31 2025 +0800

    fix nested generic type
---
 .../org/apache/fory/resolver/ClassResolver.java    | 56 +++++++++++++++++++++-
 .../org/apache/fory/resolver/TypeResolver.java     |  1 +
 .../main/java/org/apache/fory/type/TypeUtils.java  | 34 ++++---------
 3 files changed, 63 insertions(+), 28 deletions(-)

diff --git 
a/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java 
b/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java
index 11c43233f..d266c1543 100644
--- a/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java
+++ b/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java
@@ -2064,13 +2064,65 @@ public class ClassResolver implements TypeResolver {
 
   public void resetWrite() {}
 
+  private static final GenericType OBJECT_GENERIC_TYPE = 
GenericType.build(Object.class);
+
   @CodegenInvoke
   public GenericType getGenericTypeInStruct(Class<?> cls, String 
genericTypeStr) {
     Map<String, GenericType> map =
-        extRegistry.classGenericTypes.computeIfAbsent(cls, 
TypeUtils::buildGenericMap);
-    return map.get(genericTypeStr);
+        extRegistry.classGenericTypes.computeIfAbsent(cls, 
this::buildGenericMap);
+    return map.getOrDefault(genericTypeStr, OBJECT_GENERIC_TYPE);
   }
 
+  /**
+   * Build a map of nested generic type name to generic type for all fields in 
the class.
+   *
+   * @param cls the class to build the map of nested generic type name to 
generic type for all
+   *     fields in the class
+   * @return a map of nested generic type name to generic type for all fields 
in the class
+   */
+  protected Map<String, GenericType> buildGenericMap(Class<?> cls) {
+    Map<String, GenericType> map = new HashMap<>();
+    Map<String, GenericType> map2 = new HashMap<>();
+    for (Field field : ReflectionUtils.getFields(cls, true)) {
+      Type type = field.getGenericType();
+      GenericType genericType = buildGenericType(type);
+      buildGenericMap(map, genericType);
+      TypeRef<?> typeRef = TypeRef.of(type);
+      buildGenericMap(map2, typeRef);
+    }
+    map.putAll(map2);
+    return map;
+  }  
+
+  private void buildGenericMap(Map<String, GenericType> map, TypeRef<?> 
typeRef) {
+    if (map.containsKey(typeRef.getType().getTypeName())) {
+      return;
+    }
+    map.put(typeRef.getType().getTypeName(), buildGenericType(typeRef));
+    Class<?> rawType = typeRef.getRawType();
+    if (TypeUtils.isMap(rawType)) {
+      Tuple2<TypeRef<?>, TypeRef<?>> kvTypes = 
TypeUtils.getMapKeyValueType(typeRef);
+      buildGenericMap(map, kvTypes.f0);
+      buildGenericMap(map, kvTypes.f1);
+    } else if (TypeUtils.isCollection(rawType)) {
+      TypeRef<?> elementType = TypeUtils.getElementType(typeRef);
+      buildGenericMap(map, elementType);
+    } else if (rawType.isArray()) {
+      TypeRef<?> arrayComponent = TypeUtils.getArrayComponent(typeRef);
+      buildGenericMap(map, arrayComponent);
+    }
+  }
+
+  private void buildGenericMap(Map<String, GenericType> map, GenericType 
genericType) {
+    if (map.containsKey(genericType.getType().getTypeName())) {
+      return;
+    }
+    map.put(genericType.getType().getTypeName(), genericType);
+    for (GenericType t : genericType.getTypeParameters()) {
+      buildGenericMap(map, t);
+    }
+  }  
+
   @Override
   public GenericType buildGenericType(TypeRef<?> typeRef) {
     return GenericType.build(
diff --git 
a/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java 
b/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java
index 92dbdb821..1113c7d5d 100644
--- a/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java
+++ b/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java
@@ -19,6 +19,7 @@
 
 package org.apache.fory.resolver;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.Type;
 import org.apache.fory.Fory;
 import org.apache.fory.annotation.Internal;
diff --git a/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java 
b/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java
index b47a45419..03fc675d7 100644
--- a/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java
+++ b/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java
@@ -414,6 +414,14 @@ public class TypeUtils {
     return type;
   }
 
+  public static TypeRef<?> getArrayComponent(TypeRef<?> type) {
+    if (type.getType() instanceof GenericArrayType) {
+      Type componentType = ((GenericArrayType) 
(type.getType())).getGenericComponentType();
+      return TypeRef.of(componentType);
+    }
+    return TypeRef.of(getArrayComponentInfo(type.getRawType()).f0);
+  }
+
   public static Class<?> getArrayComponent(Class<?> type) {
     return getArrayComponentInfo(type).f0;
   }
@@ -909,30 +917,4 @@ public class TypeUtils {
           return false;
         });
   }
-
-  /**
-   * Build a map of nested generic type name to generic type for all fields in 
the class.
-   *
-   * @param cls the class to build the map of nested generic type name to 
generic type for all
-   *     fields in the class
-   * @return a map of nested generic type name to generic type for all fields 
in the class
-   */
-  public static Map<String, GenericType> buildGenericMap(Class<?> cls) {
-    Map<String, GenericType> map = new HashMap<>();
-    for (Field field : ReflectionUtils.getFields(cls, true)) {
-      Type type = field.getGenericType();
-      GenericType genericType = GenericType.build(type);
-      if (map.containsKey(type.getTypeName())) {
-        continue;
-      }
-      map.put(type.getTypeName(), genericType);
-      for (GenericType t : genericType.getTypeParameters()) {
-        if (map.containsKey(t.getType().getTypeName())) {
-          continue;
-        }
-        map.put(t.getType().getTypeName(), GenericType.build(t.getType()));
-      }
-    }
-    return map;
-  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to