gpt4 book ai didi

java - JDK 7 中泛型和三元运算符的编译错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:30:15 24 4
gpt4 key购买 nike

我在编写一些 Java 代码时遇到了编译失败,我将其提炼为以下测试用例:

import java.util.Collections;
import java.util.List;

public class TernaryFailure {
public static List<String> thisWorks() {
return Collections.emptyList();
}

public static List<String> thisFailsToCompile() {
return true ? Collections.emptyList() : Collections.emptyList();
}
}

上面的代码无法通过 JDK 1.7.0_45 的 javac 编译:

$ javac TernaryFailure.java
TernaryFailure.java:10: error: incompatible types
return true ? Collections.emptyList() : Collections.emptyList();
^
required: List<String>
found: List<Object>
1 error

但是,它使用 JDK 1.8.0_05 编译时没有任何错误。

这是 Java 7 实现中的错误吗?或者 Java 8 中的 Java 语言规范是否有所增强以开始允许这样做——如果是,有什么变化?

最佳答案

JLS SE 8 在 ( §15.2 ) 说:

When some expressions appear in certain contexts, they are considered poly expressions. The following forms of expressions may be poly expressions:

  • Parenthesized expressions (§15.8.5)

  • Class instance creation expressions (§15.9)

  • Method invocation expressions (§15.12)

  • Method reference expressions (§15.13)

  • Conditional expressions (§15.25)

  • Lambda expressions (§15.27)

因此从规范的这一部分可以清楚地看出,条件表达式,即三元运算符,可以被认为是多边形表达式。但并不是所有的条件表达式都可以认为是poly表达式,只能根据(§15.25)引用条件表达式.在 (§15.25.3) 中阐明了可以将引用条件表达式视为多边形表达式的条件。 :

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.

Where a poly reference conditional expression appears in a context of a particular kind with target type T, its second and third operand expressions similarly appear in a context of the same kind with target type T.

The type of a poly reference conditional expression is the same as its target type.

检查您的示例中的条件表达式是否出现在赋值上下文中,因为根据 (§14.17) :

When a return statement with an Expression appears in a method declaration, the Expression must be assignable (§5.2) to the declared return type of the method, or a compile-time error occurs.

那么归根结底,这一切意味着什么?这意味着当条件表达式是 poly 表达式时,目标类型被“下推”到每个操作数。这样,编译器可以根据目标对条件的每个部分进行归因。在您的情况下,目标是 List<String> .如果我们检查 emptyList() 方法的定义,我们有:

@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}

目标 List<String> ,编译器可以推断 T == String 并且代码被接受。

关于java - JDK 7 中泛型和三元运算符的编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23381764/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com