java - 无法在 Java 8 中将 int 转换为 long

标签 java casting java-8

我正在将我的项目升级到 Java 1.7 到 1.8。当我编译我的代码时,它给出了一个编译错误,因为int cannot cast to long

这是返回原始 long 的表达式。

public Long getOrganizationIdByUser(String userId){

        Query query = getSession().getNamedQuery("getOrganizationIdByUser");
        query.setString("id", userId!=null?_userId.toLowerCase():null);

        List<Long> returnList = query.list();
        return returnList!=null&&returnList.size()>0?returnList.get(0):0;

    }

我很困惑为什么 0 不能在 java 1.8 中转换为 long,因为这是 java 中的一个基本概念,而且它在 java 1.7 中也能正常工作。

错误

error: incompatible types: bad type in conditional expression
    [javac]         return returnList!=null&&returnList.size()>0?returnList.get(0):0;
    [javac]                                                                      
    [javac]     int cannot be converted to Long

最佳答案

数值条件表达式受制于“Binary Numeric Promotion ", 这就是为什么可以编译出以下代码的原因:

Long long1   = null;
Integer int1 = null;
Long long2 = true? long1: int1;

由于两个备选方案都有数字类型,因此应用数字提升,首先将值拆箱,然后将扩大转换应用于 int 操作数,因此条件表达式的结果类型为 。只有在之后,才会对 Long 进行装箱。

所以上面的代码有一个不直观的行为,即抛出一个NullPointerException,而不是直接将在long1中找到的对象分配给long2,由于拆箱和装箱步骤。


这同样适用于 Longint 的组合,同样当一个操作数的结果是方法调用时,例如

static Long test() {
    return Math.random()<0.5? test(): 0;
}

可以毫无问题地编译。那有什么区别呢?在例子中

public Long test() {
    List<Long> returnList = new ArrayList<Long>();
    return returnList!=null&&!returnList.isEmpty()? returnList.get(0): 0;
}

方法调用是在泛型类的实例上进行的。

The specification说:

  • If both the second and the third operand expressions are numeric expressions, the conditional expression is a numeric conditional expression.
    For the purpose of classifying a conditional, the following expressions are numeric expressions:

    • An expression of a standalone form (§15.2) with a type that is convertible to a numeric type (§4.2, §5.1.8).

    • A parenthesized numeric expression (§15.8.5).

    • A class instance creation expression (§15.9) for a class that is convertible to a numeric type.

    • A method invocation expression (§15.12) for which the chosen most specific method (§15.12.2.5) has a return type that is convertible to a numeric type.

    • A numeric conditional expression

请注意,由于引入了“独立形式”表达式,这与 Java 7 相比发生了变化,这与受目标类型约束的“多边形表达式”相反。

要检查方法调用是独立表达式还是聚合表达式,我们必须引用JLS §15.12 :

A method invocation expression is a poly expression if all of the following are true:

  • The invocation appears in an assignment context or an invocation context (§5.2, §5.3).

  • If the invocation is qualified (that is, any form of MethodInvocation except for the first), then the invocation elides TypeArguments to the left of the Identifier.

  • The method to be invoked, as determined by the following subsections, is generic (§8.4.4) and has a return type that mentions at least one of the method's type parameters.

Otherwise, the method invocation expression is a standalone expression.

在我们的例子中,最后一条不适用。此方法是泛型类的成员,但它本身不是泛型,因为它不声明类型参数,因此它的返回类型不引用方法的类型参数,因为没有.

换句话说,此方法调用是一个独立的表达式,具有数值返回类型,因此条件表达式是一个数值条件表达式,并且应该像其他示例一样进行二进制数值提升。


请注意,所有最新的 Java 9 实现都会编译此代码,就像 Java 6 和 Java 7 实现一样。

关于java - 无法在 Java 8 中将 int 转换为 long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38263265/

相关文章:

C 代码截断为最大值 7 位

java - 并行流处理 vs 线程池处理 vs 顺序处理

java - 使用 Java DateTimeFormatter 类使用 am/pm 解析一天中的时间

java - 重写父类(super class)中的私有(private)方法 - 有办法吗?

java - java 中的秒表

java - 通过命令终端在 Eclipse 中使用 JUnit 运行 java 文件

c++ - 使用 static_cast<datatype> 将 float 转换为字符串 c++

c++ - 无法从 'overloaded-function' 转换为 'QLabel *'?

Java Generics调用self类解释

java-8 - Java 8中要映射的对象列表