Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果函数参数的类型相同,为什么在Java中强制转换函数调用的两个参数是多余的?_Java_Overloading_Redundancy - Fatal编程技术网

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

如果函数参数的类型相同,为什么在Java中强制转换函数调用的两个参数是多余的?,java,overloading,redundancy,Java,Overloading,Redundancy,我很想知道casting在函数调用中是如何工作的。我的类中有两个特定函数的重载,名为execute。第一个重载是基本实现,它接受双类型参数。第二个重载接受int类型参数。第二个重载也调用基本重载,并通过将参数转换为double来实现 基本实现如下所示: public double execute(double leftVal, double rightVal) throws IOException { ... return solution; } public int exec

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

基本实现如下所示:

public double execute(double leftVal, double rightVal) throws IOException {
    ...
    return solution;
}
public int execute(int leftVal, int rightVal) throws IOException {
    return (int) execute((double) leftVal, (double) rightVal);
}
重载版本如下所示:

public double execute(double leftVal, double rightVal) throws IOException {
    ...
    return solution;
}
public int execute(int leftVal, int rightVal) throws IOException {
    return (int) execute((double) leftVal, (double) rightVal);
}

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

您可以理解重载的本质是早期绑定,编译器会验证绑定是否是编译器中合适的函数。

删除任何一个强制类型转换仍然有效,因为在调用上下文中,允许扩大原语转换。因此,Java对类型的要求不像您想象的那么严格:)

根据Java语言规范

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

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

  • 身份转换(§5.1.1)

  • 扩大原语转换(§5.1.2)

  • 拓宽参考转换(§5.1.5)

“扩大原语转换”是。。。()

19基元类型上的特定转换称为 原语转换:

  • 字节
    整数
    浮点
    ,或
    双精度

  • short
    int
    long
    float
    ,或
    double

  • char
    int
    long
    float
    ,或
    double

  • int
    long
    float
    double

  • long
    float
    double

  • float
    double

int
double
是上述转换之一,因此在调用方法时允许进行转换。另一方面,
double
int
是一种缩小原语转换,在调用上下文中是不允许的。这解释了为什么会毫不含糊地调用
(double,double)
方法

为什么上面的(双)leftVal,(双)rightVal部分是冗余的

上面的转换对于显式声明要调用该基本级别的重载函数是必要的。否则,代码将假定您希望在相同的方法中递归。因此,是的,您说的“第一次强制转换帮助编译器确定要选择哪个重载”是正确的

因此,第二种类型是隐式的。可能是因为这些类型很容易强制转换

因此,如果您要从需要较少位的基元类型(
int
为32位)转换为容纳较多位的基元类型(
double
为64位),Java知道在运行时会这样做。但是,如果您从
双精度
(64位)转换为
整数
(32位),您作为开发人员需要显式转换,因为您可能会在此处遇到信息丢失。这就是为什么(int)转换在返回时是必要的;您将从
双精度
转换为
int
,这可能是有损的

一些示例代码:

public class Test {

    public int intMethod(int intArg) {
        return intArg;
    }

    public long longMethod(long longArg) {
        // will NOT compile, since we didn't explicitly cast to narrower int type (potentially lossy)
        return intMethod(longArg);
    }
}
我一直认为Java在显式识别类型方面非常严格

原语是Java语言的一个更加微妙的特性。我认为,从类型来看,您在Java中隐式地引用了
对象
。您是对的,Java在对象转换方面要严格得多。如果我们以上面的示例为例,使用
Long
Integer
对象,它们将不会编译,并将标记一个警告
不能将java.lang.Long大小写为java.lang.Integer

由于无效转换而无法编译的示例

public class Test {

    public Integer intMethod(Integer intArg) {
        return intArg;
    }

    public Long longMethod(Long longArg) {
        return intMethod((Integer) longArg);
    }
}

ps:引用与重载方法名称相同的所有函数是标准的;将一个方法称为“base”并说其余方法重载该方法并不常见

谁告诉你强制转换是多余的?如果您真的想让int方法调用double方法,它们就不是了。@Sweeper我正在使用的IDE。我通常忽略它提供的任何语法见解,如果它们是甜的,但这是突出的,因为它听起来不应该工作。哦,你是说其中一个演员是多余的吗?你可以移除其中一个,但不能同时移除两个。哦,这很有意义。所以,我假设如果我按相反的顺序执行,我将不会得到相同的行为,并且必须显式地将每个double转换为int类型。@kohai如果按“相反的顺序”执行,您会告诉我
public class Test {

    public Integer intMethod(Integer intArg) {
        return longMethod((Long) intArg);
    }

    public Long longMethod(Long longArg) {
        return 3L;
    }
}