【问题标题】:How to get the simple generic type name?如何获得简单的泛型类型名称?
【发布时间】:2019-08-25 23:21:01
【问题描述】:

我想获得带有类型参数但没有包名的方法返回类型的字符串表示形式,例如“List”。

从返回类型的类对象中,我们可以通过method.getReturnType().getSimpleName() 得到没有包前缀但没有泛型类型参数的简单名称。输出:List

也可以通过method.getGenericReturnType().toString() 获取长格式的泛型类型参数。输出:java.util.collections.List<java.util.String>

但是如何获得一个带有泛型类型参数的简单名称呢?

例如:List<String> 而不是 java.util.collections.List<java.util.String>

【问题讨论】:

  • 可以用“.”分割(点)并读取最后一个索引。
  • 有一个getSimpleName()方法试试
  • +Warn: java.util.String 词法上与 com.anees.String 相同

标签: java generics return


【解决方案1】:

你需要编写一个简单的类,递归遍历类型并在每一层生成简单的名字:

class TypeSimpleName {

    private final Type value;

    public TypeSimpleName(Type value) {
        this.value = value;
    }

    public String getName() {
        return getName(value);
    }

    private String getName(Type type) {
        if (type instanceof ParameterizedType) {
            return getParameterizedTypeName((ParameterizedType) type);
        }
        if (type instanceof Class) {
            return getClassSimpleName(type);
        }
        // handle other types if needed

        return type.getTypeName();
    }

    private String getParameterizedTypeName(ParameterizedType type) {
        StringBuilder builder = new StringBuilder();

        builder.append(getName(type.getRawType()));
        Type[] typeArguments = type.getActualTypeArguments();
        if (typeArguments.length > 0) {
            builder.append("<");
            for (int i = 0; i < typeArguments.length; i++) {
                Type arg = typeArguments[i];
                builder.append(getName(arg));
                if (i < typeArguments.length - 1) {
                    builder.append(", ");
                }
            }
            builder.append(">");
        }

        return builder.toString();
    }

    private String getClassSimpleName(Type type) {
        return ((Class) type).getSimpleName();
    }

    @Override
    public String toString() {
        return getName();
    }
} 

使用方法:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.util.ReflectionUtils;

public class Test {

    public static void main(String[] args) {
        System.out.println(getReturnTypeName("getList"));
        System.out.println(getReturnTypeName("getListList"));
        System.out.println(getReturnTypeName("getObj"));
        System.out.println(getReturnTypeName("getMapMap"));
    }

    private static String getReturnTypeName(String method) {
        Type returnType = ReflectionUtils.findMethod(Test.class, method).getGenericReturnType();

        return new TypeSimpleName(returnType).getName();
    }

    public List<String> getList() {
        return null;
    }

    public List<List<String>> getListList() {
        return null;
    }

    public Integer getObj() {
        return 1;
    }

    public Map<String, Map<Integer, BigDecimal>> getMapMap() {
        return null;
    }
}

上面的代码打印:

List<String>
List<List<String>>
Integer
Map<String, Map<Integer, BigDecimal>>

【讨论】:

    【解决方案2】:

    您可以使用如下简单的方法遍历类型树:

      static String simpleTypeName(Type t) {
        if (t instanceof ParameterizedType) {
          ParameterizedType p = (ParameterizedType) t;
          return simpleTypeName(p.getRawType())
              + Stream.of(p.getActualTypeArguments())
                  // Recurse to handle the type arguments.
                  .map(YourClass::simpleTypeName)
                  .collect(Collectors.joining(", ", "<", ">"));
        } else if (t instanceof Class) {
          Class<?> c = (Class<?>) t;
          return c.getSimpleName();
        } else {
          // ... handle other Type subtypes.
        }
      }
    

    并像这样调用:

    String typeName = simpleTypeName(yourMethod.getGenericReturnType());
    

    Ideone demo

    【讨论】:

    • @MohamedAneesA,但是作者故意不想有包,所以应该没问题。
    • @MohamedAneesA 你现在可以在这里删除你的 cmets :)
    猜你喜欢
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多