我有一个名为 Employee
的界面和两个实现类 FullTimeEmployee
和PartTimeEmployee
。在一个单独的类(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>
但是,如果我将三进制打开为标准 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 语句之外,您可以执行我所看到的两件事之一:
- 将整个条件表达式转换为
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/