Overloading methods - java

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.

Related

Why method call is giving error?

When I am writing this code I am getting error
public class MethodOverloading
{
void m(short i)
{
System.out.println("SHort");
}
public static void main(String[] args)
{
MethodOverloading ml=new MethodOverloading();
ml.m(10);
}
}
I am getting error that m(short) is not applicable for m(int) but when I am
assigning int value to short then no error then if am not able to pass int
value as an argument to method that accepts short then how short variable is accepting int value as below?
short d=10;
System.out.println(d);
Narrowing conversion can occur in an assignment unlike literals being passed to a method. From the JLS
A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.
You have to cast the int to short, because 10 is considered like an int not a short :
ml.m((short)10);
m1.m((short) 10);
Cast the 10 (since there's no type associated with it Java assumes it's a 32-bit int instead of a 16-bit short) to a short.
This is static binding, and the assignment operator '=' is not strict on down casting.But method binder is strict on type. Just imagine you have one more method void m(int i) along with void m(int i) the method binder must bind the call to the right method. So it must be strict.
In short s = 10 case, jdk will downcast the value on compilation, so the value will be assigned to s will be down caste of short 10, also if you try to assign a real int range value say 99999999 it will not compile.
Finally static method binding is strict on type.

Overloaded Method calling in 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)!

The output of the following program is 1,3,3 can someone explain it how?

The output of the following program is 1,3,3 can someone explain it how?
will it consider 10.25 as a object to the method argument?
public class Test {
void methodOfTest(int i) {
System.out.println(1);
}
void methodOfTest(Integer I) {
System.out.println(2);
}
void methodOfTest(Object o) {
System.out.println(3);
}
public static void main(String[] args) {
Test t = new Test();
t.methodOfTest(10);
t.methodOfTest(10.25);
t.methodOfTest(new Double("25.25"));
}
}
t.methodOfTest(10);
10 is interpreted as int literal, so methodOfTest(int i) is called
t.methodOfTest(10.25);
There is no method, that takes a double, so the only method where 10.25 fits in is methodOfTest(Object o)
t.methodOfTest(new Double("25.25"));
Here we have a Double object, but again, no method is found that takes a Double, so the only method that takes this is again methodOfTest(Object o).
Therefore your output is 1,3,3.
It does not consider 10.25 to be an object. It does consider it to be assignment-convertible to an Object reference, by boxing conversion to a Double reference followed by widening reference conversion.
The boxing answers are absolutely correct.
I just wanted to add this: you were perhaps expecting an automatic (implicit) conversion from Double to Integer, but such a conversion must be declared explicitly (casting Double to Integer).
Without an explicit conversion, your Double value is interpreted as an Object (since you provided that method overload), which is the base class of about everything.
Hope this helps ;)
Because 10.25 can be converted to a Double. (boxing into Double)
So the constructor of Double will be called with 10.25 as parameter and will be passed to the method : void methodOfTest(Object o).

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.

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)

Categories