Java Casting in Method Overloading

I have the methods overloading such as:

 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; 
}

From the main method, suppose we have

 double x=10.10f;
 double y=10.20f; 

the apparent type for x and y is double, but the actual type is float. when I call

System.out.println(" the output is :"+cc.sum1(x,y)); 

the error in the compile-time.

The method sum1(int, int) in the type Class is not applicable for the arguments double, double). 

where it should go to sum1 (i.e. method3) by casting double to float

Jon Skeet
people
quotationmark

TL;DR version of this answer:

  • Variables of primitive types never have a different type at execution-time to their compile-time. (A double is always a double, never a float, etc.)
  • Overload resolution (picking which method signature is used) is performed using the compile-time types of expressions
  • Method implementation of the picked signature is performed using the execution-time type of the target of the method call

the apparent type for x and y is double, but the actual type is float

No, it's not. You've just got a conversion from the assigned float literals to double values. The actual values are double.

Primitives don't work like objects - there's no idea of an int value still being an int inside a double variable, for example.

It's simpler to take an example with integer types. Suppose we have:

byte b = 100;
int x = b;

The value of x is the 32-bit integer representing the value 100. It doesn't "know" that it was originally assigned from a byte value... there just happened to be a conversion from byte to int at the point of assignment.

Compare that with reference types:

String x = "hello";
Object y = x;

Here, the value of y really is a reference to a String object. That type information is preserved precisely because there's a whole object that can contain it, and because the value of the variable itself is only a reference. (The bits themselves don't need to change as part of the assignment - in a simple VM at least, they'll be the exact same bits in x and y, because they're referring to the same object.)

Even in that case, however, overload resolution occurs based on the compile-time type of the arguments, not their actual values at execution time. The only way that the execution-time type of a variable gets involved is with overriding based on the target of a method call. So if we have:

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

f.someMethod(g, h);

... then the compiler will look for a method in Foo which has two Foo parameters (or Object or other superclasses/interfaces) - the actual types of the objects involved are irrelevant. At execution time, however, if that method has been overridden in X, then that override will be called due to the execution-time type of the object f's value refers to.

people

See more on this question at Stackoverflow