有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

基于内部映射的java通用返回类型?

我有一个函数,它试图将字段名(字符串)映射到类类型,然后能够根据输入字段名将输入字符串转换为正确的类型

public class Parser {
  private final Map<String, Class> mapping;
  public Parser(Map<String, Class> inputMapping){
    this.mapping = inputMapping;
  }

  public T parseString(String fieldName, String parseValue){
     Object convertedObject;
     Class<T> classType = mapping.get(fieldName);
     if(classType == String.class) {
       convertedObject = parseValue;
     } else if (classType == Double.class) {
       convertedObject = Double.valueOf(parseValue);
     } else {
       throw new UnimplementedException("Invalid type");
     }
     return classType.cast(convertedObject);
  }
}

我在这方面遇到了一些错误,比如“找不到符号‘T’”,这是指在parseString的返回类型中使用的T。是否有方法纠正此错误或重新组织函数,使其具有相同的行为

谢谢


共 (1) 个答案

  1. # 1 楼答案

    你试图在这里做一些在Parser类中做不到的事情

    Java方法有固定的返回类型。它可以是泛型的,但不能在方法内部选择值的返回类型。返回的显然可以,但返回的类型是固定的

    这里要做的是将特定字段解析为特定类型。在你试图使用它的意义上,“字段”实际上是一个Function<String, SomeType>。如果知道所需字段的类型,则必须知道字段的名称。因此,与其说:

    Integer i = parser.get("int_field", "1");  // Can't do this.
    Double d = parser.get("double_field", "1");  // Can't do this.
    

    相反,你可以做:

    Function<String, Integer> intFieldParser = Integer::parseInt;
    Function<String, Double> doubleFieldParser = Double::parseDouble;
    
    Integer i = intFieldParser.apply("1");
    Double d = doubleFieldParser.apply("1");
    

    也就是说,通过将解析器分开来保留类型信息。这样就完全不需要Parser

    如果必须将内容放入映射(例如,在编译时您不知道字段),那么最好返回一个公共超类型:

    Number i = parser.parse("int_field", "1");
    Number d = parser.parse("double_field", "1");
    

    值可以是IntegerDouble;但是客户端代码必须解决这个问题;你不能在编译时知道它