方法重载中的Java转换

Meh*_*014 1 java casting overloading

我有方法重载,如:

 public int sum1(int a, int b)
{
    int c= a+b; 
    System.out.println("The method1");
    return c; 
}
public float sum1(int a, float b)
{
    float c=  a+b;
    System.out.println("The method2");
    return c; 
}
public double sum1(float a, float b)
{
    double c=  (double) a+b;
    System.out.println("The method3");
    return c; 
}
Run Code Online (Sandbox Code Playgroud)

从主要方法,假设我们有

 double x=10.10f;
 double y=10.20f; 
Run Code Online (Sandbox Code Playgroud)

x和y的表观类型是double,但实际类型是float.我打电话的时候

System.out.println(" the output is :"+cc.sum1(x,y)); 
Run Code Online (Sandbox Code Playgroud)

编译时的错误.

The method sum1(int, int) in the type Class is not applicable for the arguments double, double). 
Run Code Online (Sandbox Code Playgroud)

它应该通过将double转换为float来转到sum1(即method3)

Jon*_*eet 11

TL;这个答案的DR版本:

  • 原始类型的变量在执行时到编译时从不具有不同的类型.(A double总是a double,永远不是a float等)
  • 使用编译时类型的表达式执行重载决策(选择使用哪个方法签名)
  • 使用方法调用的目标的执行时类型来执行拾取签名的方法实现

x和y的表观类型是double,但实际类型是float

不,这不对.您刚刚从指定的float文字转换为double值.的实际值double.

基元不像对象那样工作 - 例如,不知道int值仍然是变量int内部double.

以整数类型为例更简单.假设我们有:

byte b = 100;
int x = b;
Run Code Online (Sandbox Code Playgroud)

x是32位整数,表示值100.它不"知道"它最初是从一个byte值分配的......恰好是在转移点byte到转换int点.

将其与参考类型进行比较:

String x = "hello";
Object y = x;
Run Code Online (Sandbox Code Playgroud)

这里,值的y实际值String对象的引用.该类型信息被精确保留,因为有一个完整的对象可以包含它,并且因为变量本身的值只是一个引用.(该位本身并不需要更改为任务的一部分-在一个简单的虚拟机至少,他们会在完全相同的比特xy,因为他们指的是同一个对象.)

但是,即使在这种情况下,也会根据参数的编译时类型而不是执行时的实际值来进行重载解析.变量的执行时类型涉及的唯一方法是基于方法调用的目标进行覆盖.所以如果我们有:

Foo f = new X();
Foo g = new Y();
Foo h = new Z();

f.someMethod(g, h);
Run Code Online (Sandbox Code Playgroud)

...然后编译器将寻找一个方法,Foo其中有两个Foo参数(Object或其他超类/接口) - 所涉及对象的实际类型是无关紧要的.但是,在执行时,如果已覆盖该方法X,则由于对象f值的执行时类型引用,将调用该覆盖.