Overloaded Method calling in Java - java

Let's say I have 2 methods as such:
1 public int sum(int a, int b) { return a + b; }
2 public double sum(double a, double b) { return a + b; }
If I call sum, like so: sum(2, 3)
The first method will be executed
If I call sum, like so: sum(2.5,3.5)The second method is executed
However, if I call sum like such: sum(2.5,3), the second method is executed, but not the first, why is that?
Also, would this also be the case if sum was called as such: sum(3,2.5)?

The compiler will make the int into a double, calling the second method It is because, an int can be typecasted into a double, but not vice versa.
This will apply for all the primitive types going to the right. You can't go to the left, unless you explicitly typecast, which you aren't doing. If you wanted the first method to be executed, you could just typecast into an int, so that it doesn't widen into a double. Java is very specific about these things:
SO, in conclusion, when you call the method without typecasting the int, doing this:
sum(int, double);
is actually translating to this:
sum(double, double);
and to avoid this, you must typecast your int as an int.

Because, integers can be as floating-point numbers in Math.
So, sum(3,2.5) - here worth method signature is sum(double, double)!

Related

Overloaded function throws an error for float arguments

This is my Java program code. I overloaded the add function for the data types int and float, but the call add(2.3, 2.4) throws an error, instead of calling add(float, float).
public class Main {
public static void main(String[] args) {
// This calls add(int, int) as expected
System.out.println(add(2,4));
// This call throws an error
System.out.println(add(2.3,3.4));
}
public static int add(int a, int b){
return (a + b);
}
public static float add(float a, float b){
return (a + b);
}
}
You defined the overloaded methods correctly!
What you got wrong is the way you call the methods. You are calling add(2.3,3.4). 2.3 and 3.4 are all doubles. That's why they can't be directly put into a method that accepts floats.
"What? Why are they doubles?" you might ask.
By default, all number literals without a . or e are considered to be ints. And all number literals that has either or both a . or e are considered to be doubles.
To create a float literal, add f to the end of the numbers. i.e. these are all floats:
1f
1000f
1.1f
-9f
1e99f
So you should call your method like this
add(2.3f,3.4f)
There are add methods for int and float, while literal 2.3 has type double. There two ways to fix this:
Use float literals, i.e. 2.3f and 3.4f (notice the f suffix).
Define add method for doubles.

Denote method parameter as "short" primitive type

I have a method that accept one parameter of type short.
public void doSomething(short value) {
//DO STUFF
}
And I can call it this way:
short value = 3;
doSomething(value);
But not this another one:
doSomething(3);
Why? Is there a way to denote that this parameter is a short and not an int?
You can call it this way :
doSomething((short)3);
Without casting, 3 will always be an int literal.
The reason
public void doSomething(short value) {
//DO STUFF
}
can be called as
short value = 3;
doSomething(value);
cause value is already short
When you call it like doSomething(3); 3 is considered as integer and cannot be casted to short implicitly.
Basically doSomething(3); would require a
public void doSomething(int value) {
//DO STUFF
}
method to go with.
However you can cast 3 to short and can call the method as:
doSomething((short)3);
In Java, arithmetic expressions on the right hand side of the assignment evaluates to int by default. Look at this surprising example:
short a = 1;
short b = 2;
short c = a + b; // Error!
You need to explicitly cast to short as already mentioned in other answers, or change the method's signature to accept int instead.
It's worth mentioning that in terms of space short takes the same space as int if they are local variables, class variables or even instance variables since in most systems, variables addresses are aligned, I would simply change the signature of the method to accept an int instead and wouldn't complicate things.

Reading Overloading Methods

I saw a question online that asks if you are given the print statements,
System.out.println(M.m(4.0, 5));
System.out.println(M.m(4, 5.0));
I understand that a double can be used as an int, so the first method will be printed. i.e 40.0.
But for the second print statement, wouldn't the same logic be used, and the first method be printed again? Java is saying the second print statment is 60.0.
public static double m(int a, int b) {
return a * b;
}
public static double m(double a, int b) {
return a * b * 2;
}
public static double m(double a, double b) {
return a * b * 3;
}
Actually, for the first print, the second overload will be used, because the parameter types match exactly: double and int.
For the second print, the third overload will be used, because double is not automatically promoted to int. The only method whose second parameter is promotable from double is the third overload - and that will force the first parameter to be promoted to double.
Since there's only one method that accepts double as the second parameter, the first parameter is going to be coerced into a double, so it would be called as M.m(4.0, 5.0) instead, thus falling into the third method.

Java overload confusion

java is not able to call any overload method as shown below :-
class LspTest{
public void add(int a, float b){
System.out.println("First add");
}
public void add(float a, int b){
System.out.println("second add");
}
public static void main(String [] a){
LspTest test = new LspTest();
test.add(1,1);
}
}
Please explain i am confused in this.
In your methods you are having parameters (int, float) and (float, int) but when calling the method you are passing both the int (1,1) values. The Java complier can auto type cast float to int whenever needed. But in this case compiler cannot decide auto type cast which int to float. Therefore it shows ambiguity.
You need to call it test.add(1f, 1); or test.add(1,1f); i.e. specify which value is int and which value is float.
P.S. To specify a value to be float you can write f with it.
When you initialise with literal values, in this case, compiler won't be able to infer the exact type. Therefore, it does not know which overload to call and returns the error that the reference to add is ambiguous. You can fix this by casting the arguments to the appropriate type, or even better, creating typed local variables initialised with 1 and passing the variables as parameters, like so:
int a = 1;
float b = 1;
LspTest test = new LspTest();
test.add(a,b);
There is an ambiguity here, and the Java compiler cannot figure out which method to call. Use test.add((float) 1, 1) or test.add(1, (float) 1) to explicitly tell which method you want.
This is the clear case of ambiguity which leads to a Compile Error.
Java compiler supports the type promotion. First of all, it'll checks for more specific data type if not match then it'll promote to next data type.
Java compiler will supports the type promotion in following order.
byte --> short --> int --> long --> float --> double
As your parameters (int,int) can be auto-promoted to float, java compiler can't decide in which one to invoke as both of your methods accepts the (1,1)

Overloading methods

I saw below question posted on this site.
"What happens when we pass int arguments to the overloading method having float as a parameter for one method and another having double param".
I thought I understood the concept and wrote this code:
public class TestClass {
public static void main(String args[])
{
TestClass t=new TestClass();
t.sum(1/4);
}
void sum(double d)
{
System.out.println("Double==="+d);
}
void sum(int i)
{
System.out.println("Integer==="+i);
}
void sum(short s)
{
System.out.println("Short==="+d);
}
}
According to my understanding explained on this site (as mentioned above), I thought it will print Short===0, but to my surprise it prints Integer===0. Can any one explain this to me?
First of all, these are overloaded methods, not overridden methods.
1 and 4 are integers. Therefore 1/4 is an integer division, returning 0.
Therefore, the method being called is sum(int i).
sum(short s) would never be called for an int parameter, since that would require a narrowing primitive conversion (JLS 5.1.3), that may cause data loss, and is not allowed in method invocation conversion (JLS 5.3). Such a conversion can be done with an explicit cast.
If you remove the int version, sum(double d) would be called, and if you remove the double version, the code won't compile.
In order to call the short version, you must cast the parameter to short :
t.sum ((short)(1/4));
If you don't explicitly tell the compiler what are the types of 1 and 4, it assumes they are of type int. Then, / operator will apply integer division and will produce another int (which will be 0.)
After that, the method with the most specific to integer parameter type will be invoked. In your case, this will be sum(int i).
If you want to invoke some of the other overloaded methods, you will have to explicitly:
do a cast. For example, sum((short) (1/4)); will invoke sum(short s) due to the cast.
point the type of the operands. For example, sum(1d/4) will invoke sum(double d), since 1d/4 will result to double
For integer number, the type int is a default choice. So, although 1 and 4 can be defined as both int or short, since you did not defined anything, the compiler identified 1 and 4 as int and therefore it entered into the function for 1/4 division (0), which took the parameter int.

Categories