【问题标题】:Java generic bi-function to return value based on specified class type基于指定类类型返回值的 Java 通用双函数
【发布时间】:2020-01-29 00:27:51
【问题描述】:

我正在尝试编写通用 Json 反序列化器,如下所示,

  public static <T> BiFunction<String, Class<T>, T> jsonDeSerializer() {
    return (o, c) -> {
      try {
        return mapper.readValue(o, c);
      } catch (IOException e) {
        logger.error("json.parse.error object.type={}", o.getClass().getSimpleName(), e);
        throw new JsonProcessingEx(e);
      }
    };
  }

当我试图打电话时,我得到了

error: incompatible types: Class<MLAdhocResponseVO> cannot be converted to Class<Object>
    MLAdhocResponseVO response = JsonUtils.jsonDeSerializer().apply("{}", MLAdhocResponseVO.class);

我只想写一个 BiFunction,它根据提供的类返回 Object,而不需要任何类型转换。

【问题讨论】:

    标签: java java-8


    【解决方案1】:

    当你打电话时

    JsonUtils.jsonDeSerializer().apply("{}", MLAdhocResponseVO.class);
    

    jsonDeSerializer() 的泛型类型参数是 Objectthisthis 可以提供更多信息),而不是您所期望的 MLAdhocResponseVO

    快速解决方法是在调用中添加一个类型见证,以告诉编译器您对该方法的预期类型参数是什么:

    MLAdhocResponseVO response = JsonUtils.<MLAdhocResponseVO>jsonDeSerializer()
            .apply("{}", MLAdhocResponseVO.class);
    

    或者,您可以通过声明类型化的BiFunction 变量来为编译器提供目标类型:

    BiFunction<String, Class<MLAdhocResponseVO>, MLAdhocResponseVO> 
                            function = jsonDeSerializer();
    MLAdhocResponseVO response = function.apply("{}", MLAdhocResponseVO.class);
    

    如果你想完全避免这种情况,那么你的方法可能会更好地设计一个泛型类型的实际参数,这将有助于编译器的类型推断:

    public static <T> Function<String, T> jsonDeSerializer(Class<T> c) {
        return (o) -> {
            try {
                return mapper.readValue(o, c);
            } catch (IOException e) {
                logger.error("json.parse.error object.type={}", 
                       o.getClass().getSimpleName(), e);
                throw new JsonProcessingEx();
            }
        };
    }
    

    这样,您的代码无需类型见证即可编译:

    MLAdhocResponseVO response = JsonUtils.jsonDeSerializer(MLAdhocResponseVO.class)
        .apply("{}");
    

    甚至这个独立的表达式也输入正确:

    JsonUtils.jsonDeSerializer(MLAdhocResponseVO.class)
            .apply("{}");
    

    【讨论】:

    • 我的错,我怎么能错过初始类型转换:(,但是最后一种方法似乎很干净,最好从更清洁和可用的 API 角度解决这种情况。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2018-07-24
    相关资源
    最近更新 更多