【问题标题】:Generic return type based on inner map?基于内部映射的通用返回类型?
【发布时间】:2018-07-27 19:29:42
【问题描述】:

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

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

我收到了错误,尽管在引用 parseString 的返回类型中使用的 T 时说“找不到符号 'T'”。无论如何要纠正这个错误或重新组织函数以具有相同的行为?

谢谢!

【问题讨论】:

  • 您不能安全地执行此操作。您所能做的就是返回Object
  • public &lt;T&gt; T parseString
  • @Aominè.... 这不是类型安全的,因为您可以调用 Integer i = parseString("field", "parse");Double d = parseString("field", "parse");
  • @AndyTurner 我没有太注意描述,但肯定解决了 OP 遇到的编译错误。
  • @Aominè 不要将编译时错误更改为运行时错误。前者比后者更容易捕捉。

标签: java class generics casting


【解决方案1】:

您正在这里尝试做一些在Parser 类中无法完成的事情。

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

您在这里尝试做的是将特定字段解析为特定类型。在您尝试使用它的意义上,“字段”实际上是Function&lt;String, SomeType&gt;。如果您知道您期望的字段类型,您必须知道该字段的名称。所以,而不是:

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;但是客户端代码必须解决这个问题;你在编译的时候是不知道的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 2015-03-28
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    相关资源
    最近更新 更多