java - 多态性在三元中失败,但在标准条件中通过(捕获?)

标签 java polymorphism conditional-operator objectmapper

我有一个名为 Employee 的界面和两个实现类 FullTimeEmployeePartTimeEmployee 。在一个单独的类(class)中,我尝试使用 ObjectMapper分配正确的类(class)。方法如下

public Employee retrieveEmployee(String employeeId){
  Employee employee;
  var jsonString = lookupEmployee(employeeId);
  employee = new ObjectMapper().readValue(jsonString, isFullTime(employeeId) ? FullTimeEmployee.class : PartTimeEmployee.class;
  return employee;
}

这在 IDE 中给了我一个编译器错误,其中所需类型为 Class <capture of ? extends Employee> ,但提供的是Class <FullTimeEmployee>

enter image description here

但是,如果我将三进制打开为标准 if...then ,一切正常。

  if (isFullTime(employeeId)){
    employee = new ObjectMapper().readValue(jsonString, FullTimeEmployee.class);
  } else {
    employee = new ObjectMapper().readValue(jsonString, PartTimeEmployee.class);
  }

这里发生了什么,为什么其中一个有效,而另一个不起作用?

最佳答案

当您将条件表达式编写为方法调用的参数时,它是 poly expression .

A reference conditional expression is a poly expression if it appears in an assignment context or an invocation context (§5.2. §5.3). Otherwise, it is a standalone expression.

将这样的条件表达式传递给方法调用是一个调用上下文,因此您有一个聚合表达式。

什么是多重表达式? This site比 Java 教程或 JLS 更好地解释了 Poly 表达式:

First, for some expressions, termed poly expressions, the deduced type can be influenced by the target type. The same expression can have different types in different contexts.

这意味着条件表达式的类型受目标类型的影响。因为 jackson 的readValue方法是泛型的,第二个参数的目标类型Class<T>变成Class<Employee>基于 Employee 的返回类型.

但是由于Java的泛型是不变的,a Class<FullTimeEmployee>不是Class<Employee> ,以及 Class<PartTimeEmployee>也不是。

但是,如果条件表达式不是聚合表达式(独立表达式),则可以在没有上下文(例如目标类型)的情况下确定其类型。在本例中,它是 Class<? extends Employee> .

要消除由于 Poly 表达式导致的类型不匹配,除了将条件表达式替换为 if-then 语句之外,您可以执行我所看到的两件事之一:

  1. 将整个条件表达式转换为 Class<? extends Employee> 。这使得它根本不是一个多重表达式。
employee = new ObjectMapper().readValue(jsonString,
    (Class<? extends Employee>) (isFullTime(employeeId) ? FullTimeEmployee.class : PartTimeEmployee.class));
  • 或者将条件表达式拆分为自己的语句。它仍然是一个多元表达式,但目标类型推断现在匹配。
  • Class<? extends Employee> c = isFullTime(employeeId) ? FullTimeEmployee.class : PartTimeEmployee.class;
    Employee employee2 = om.readValue(jsonString, c);
    

    关于java - 多态性在三元中失败,但在标准条件中通过(捕获?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73653663/

    相关文章:

    c# - 多态重载——为了重载参数,如何将抽象类型强制为 "act"作为其派生类型之一?

    c++ - 如何正确重载流运算符以在多态类中进行打印?

    c++ - 重载和覆盖如何协同工作?

    c++ - 条件运算符的局限性? :

    julia - Julia中多个条件的三元运算符

    java - 按属性在列表中查找特定对象

    java - 按数值降序对 Hashmap 键进行排序

    c - 如何将 AVX vector 与 clang 原生 vector 语法(无内在函数)混合?

    java - 相当于 webmin 的 Java 是什么?

    java - 编译时出现不兼容类型问题 - void to MimeMessage