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)
Related
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.
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)!
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.
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.
Can someone please explain how/why is this allowed in Java?
public class Test {
private int text;
public Integer getText() {
return text;
}
I am basically having the wrapper class as the return type, while I am infact returning a primitive.
Because Java supports Autoboxing and Unboxing in versions 5 and up. That is an example of the former, but the later is equally important (and the reverse conversion). Per the link,
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes.
Consider the following code: (From: http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(i);
Although you add the int values as primitive types, rather than Integer objects, to li, the code compiles. Because li is a list of Integer objects, not a list of int values, you may wonder why the Java compiler does not issue a compile-time error. The compiler does not generate an error because it creates an Integer object from i and adds the object to li. Thus, the compiler converts the previous code to the following at runtime:
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(Integer.valueOf(i));
Converting a primitive value (an int, for example) into an object of the corresponding wrapper class (Integer) is called autoboxing. The Java compiler applies autoboxing when a primitive value is:
Passed as a parameter to a method that expects an object of the corresponding wrapper class.
Assigned to a variable of the corresponding wrapper class.
From javadocs : Since java 5 Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on.
The java compiler applies autoboxing usually when -
Passed as a parameter to a method that expects an object of the
corresponding wrapper class.
Assigned to a variable of the corresponding wrapper class.
For the sake of performance, not everything in Java is an object. There are also primitives, such as int, long, float, double, etc.
For example java.lang.Integer class :-
It wraps an int.
Has two static final fields of type int: MIN_VALUE and MAX_VALUE.
MIN_VALUE contains the minimum possible value for an int (-2^31) and MAX_VALUE the maximum possible value for an int (2^31 - 1).
It also has two constructors - public Integer (int value) & public Integer (String value).
Integer has the no-arg byteValue, doubleValue, floatValue, intValue, longValue, and shortValue methods that convert the wrapped value to a byte, double, float, int, long, and short, respectively.
In addition, the toString method converts the value to a String.
Static methods parse a String to an int (parseInt) and convert an int to a String (toString).
class AutoBox {
public static void main(String args[]) {
// autobox an int
Integer a = 100;
// auto-unbox
int b = a;
System.out.println(b + " " + a); // displays 100 100
}
}
This feature has been added in Java 5.
text gets converted automatically into Integer by compiler. So basically its a syntactic sugar that can shorten your code (otherwise you would do conversions back and forth by yourself). Of course it has its price and if this happens a lot (I mean really a lot, big loops, frequent invocations and so forth), it can become a performance issue, so when using it, just remember the it happens under the hood and you'll be fine.
Integer.valueOf(text)
is called under the hood
The feature is called autoboxing btw
Hope this helps