In Java, suppose we have a function with the parameter double a
. Does it work if I pass an integer as argument? (I mean, is there an implicit conversion?) And in the opposite case: if I have e.g. an integer as parameter, and I pass a double?
Unluckily, I am not able to compile my code at the moment, and I would like to check this assert. Thank you for your attention.
See JLS - Section # 5.3 for details on Method Invocation Conversion
.
Method invocation contexts allow the use of one of the following:
- an identity conversion (§5.1.1) - a widening primitive conversion (§5.1.2) - a widening reference conversion (§5.1.5) - a boxing conversion (§5.1.7) optionally followed by widening reference conversion - an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.
So, your first invocation(int
to double
) will work fine according to rule # 2.
But the second invocation(double
to int
) will give Compiler Error, according to the statement quoted further in the same section: -
If the type of the expression cannot be converted to the type of the parameter by a conversion permitted in a method invocation context, then a compile-time error occurs.
Initially primitive widening will happen for a primitive type. For example you want to call
int input = 5; //int variable;
apply(input); //calling method with int value.
But your class not contains a method which argument accept int so compiler will go for primitive widening. It will check any apply method with java long argument present or not. If present that method will be invoked. If not it will check for apply with a float argument is present and then it will be selected. If that also not find it will look for apply with a double argument.
public void apply(long input) {
System.out.println("long"); // first pick by the compiler.
}
public void apply(float input) {
System.out.println("float"); // if above method not found this will be selected.
}
public void apply(double input) {
System.out.println("double"); // above two methods not present this will be selected.
}
Next, If all above three methods not found then compiler will look for Autoboxing this and try to convert that to its corresponding wrapper. for int its java.lang.Integer.So it will check for apply with Integer argument. If this found compiler will execute this method.
public void apply(Integer input) {
System.out.println("Integer");
}
Finally if none of the above present, compiler looks for any method with name apply which accepts int... or Integer... and the method is invoked.
public void apply(int... input) {
System.out.println("int...");
}
If your class contains only below two methods
public void apply(long input) {
System.out.println("long");
}
public void apply(float input) {
System.out.println("float");
}
and you want to pass a double value in to this method, it wont compile.
double input = 5d;
apply(input);
// The method apply(long) in the type YourClass
//is not applicable for the arguments (double
If you want to make that work you have to type cast that to something which can be accepted by your methods.
apply((int) input);
Then compiler will try to find a match by exact type or primitive widening or autoboxing or array matching way.
Because you can set a double to an integer, then integer as argument is ok to function with double as parameter. Other way round fails. In that case you need to cast the double to an int. Same applies to normal assignents eg..
int i = 6;
double d = 0;
d = i; /* ok
i = d ; /* not ok
You can get sometimes get around this by making your function take a parameter of Number
. This is an Object which both Integer
and Double
inherit from, so up to the point where a Double
number and an Integer
number behave the same, this will work.
Note that there is a difference between the primitives integer
and double
and the Objects Integer
and Double
. Java uses autoboxing to automatically convert between these types in function calls, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With