如果函数参数类型相同,为什么在 Java 中强制转换函数调用的两个参数是多余的?

koh*_*hai -1 java redundancy overloading

我很想知道转换在函数调用中是如何工作的。我的类中有两个特定函数的重载,称为execute. 第一个重载是基本实现并接受double类型参数。第二个重载接受int类型参数。第二个重载也调用基本重载,并通过将参数强制转换为double

基本实现如下所示:

public double execute(double leftVal, double rightVal) throws IOException {
    ...
    return solution;
}
Run Code Online (Sandbox Code Playgroud)

重载版本如下所示:

public int execute(int leftVal, int rightVal) throws IOException {
    return (int) execute((double) leftVal, (double) rightVal);
}
Run Code Online (Sandbox Code Playgroud)

为什么上面的(double) leftVal, (double) rightVal部分,特别是部分,是多余的,为什么它可以在删除一个演员表的情况下工作?在第一个重载的调用工作无论何种顺序铸造中,两者execute(leftVal, (double)rightVal)execute((double) leftVal, rightVal)正常执行,不产生错误。我一直认为 Java 在明确识别类型方面非常严格。我希望有一些警告或错误,即不存在接受调用之类的函数execute(double, int)。不过,我有一个想法,即第一个强制转换有助于编译器确定选择哪个重载,因此第二个强制转换是隐式的。也许是因为这些类型是原始的,易于强制转换?还有一个小问题,两个函数都称为重载还是第一个定义之后的每个定义都是原始函数的重载?

Swe*_*per 6

删除任一类型转换仍然有效,因为在调用上下文中,允许扩展原始转换。所以不,Java 对类型没有你想象的那么严格:)

根据 Java 语言规范§5.3 调用上下文

调用上下文允许将方法或构造函数调用(第 8.8.7.1 节、第 15.9 节、第 15.12 节)中的参数值分配给相应的形式参数。

严格的调用上下文允许使用以下之一:

  • 身份转换(第 5.1.1 节)

  • 扩大原始转换(第 5.1.2 节)

  • 扩大参考转换(第 5.1.5 节)

“扩大原始转换”是...(§5.1.2

原始类型的 19 种特定转换称为扩展原始类型转换:

  • byteshortintlongfloat,或者double

  • shortintlongfloat,或者double

  • charintlongfloat,或者double

  • intlong, float, 或double

  • longfloatdouble

  • floatdouble

inttodouble是上述转换之一,因此在调用方法时是允许的。另一方面,doubletoint是一种缩小原语转换,在调用上下文中是不允许的。这解释了为什么明确调用该(double, double)方法。