基于内部地图的通用返回类型?

时间:2018-02-16 20:27:03

标签: java class generics casting

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

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

我发现错误虽然说'#34;找不到符号&#39; T&#39;&#34;参考在parseString的返回类型中使用的T.是否有纠正此错误或重新组织函数以具有相同的行为?

谢谢!

1 个答案:

答案 0 :(得分:1)

您正在尝试在Parser课程中执行某些操作。

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

您在此尝试执行的操作是将特定字段解析为特定类型。在某种意义上,你正试图使用​​它,一个&#34;字段&#34;实际上是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;但客户端代码必须解决这个问题;你无法在编译时知道它。