Java - why no return type based method overloading?
Because you are not required to capture the return value of a method in Java, in which case the compiler can not decide which overload to use. E.g.
boolean doSomething() { ... }
int doSomething() { ... }
doSomething(); // which one to call???
Why is the return type not considered when differentiating methods?
Because it's not required to assign the result when you want to execute a method. How would the compiler then know which of the overloaded ones you'd like to call? There will be ambiguity.
Does Java virtual machine allow overloading on return type?
These statements are perfectly true.
Remember that Java is two things - one,a language and two, a virtual machine. While restricting the language to not allow type based method overloading makes Java a simpler language to use, the JVM can still allow this to be done to make it more powerful.
As a language, Java has a compiler that enforces the rules that make Java a simpler, easier programming language than one that does allow this. To do this, it restricts what you can do, but only in the Java language itself. Running something like Scala or Ruby on the JVM requires different rules and features, and at this level it is important that the JVM allows the flexibility that has made the JVM such a big success that it is found on so many platforms and devices.
In a language where overloading by return type is possible, it would be very error prone and the decision to not support that feature was deliberate to make Java a less error-prone programming language. How would the compiler know which function you intended to call?
The JVM on the other hand is a low-level, highly optimised virtual machine that exists to run bytecode, not Java. It is therefore not wise to restrict the JVM in this fashion as it should be able to run bytecode not generated from Java at all.
Another example would be multiple inheritance, which is not available in Java, yet nothing prevents you to write a language that supports multiple inheritance and have it compile to bytecode. It would make your language more difficult to use and potentially more error prone, but if you require that feature, the JVM will not stop you.
Overload with different return type in Java?
You can't do it in Java, and you can't do it in C++. The rationale is that the return value alone is not sufficient for the compiler to figure out which function to call:
public int foo() {...}
public float foo() {..}
...
foo(); // which one?
Why is method overloading not defined for different return types?
You can of course have overloading for methods which differ by return type, just not for methods which differ only by return type. For example, this is fine:
def foo(s: String) : String = s + "Hello"
def foo(i: Int) : Int = i + 1
That aside, the answer to your question is evidently that it was a design decision: the return type is part of the method signature as anyone who has experienced an AbstractMethodError
can tell you.
Consider however how allowing such overloading might work in tandem with sub-typing:
class A {
def foo: Int = 1
}
val a: A = //...lookup an A
val b = a.foo
This is perfectly valid code of course and javac
would uniquely resolve the method call. But what if I subclass A
as follows:
class B extends A {
def foo: String = "Hello"
}
This causes the original code's resolution of which method is being called to be broken. What should b
be? I have logically broken some existing code by subtyping some existing class, even though I have not changed either that code or that class.
why java compiler can't decide which method to call based on return type
You're looking at the compiled code, i.e. you're assuming the compiler can decide which method to compile. But the problem is it can't (for the same reason in the answer to the mentioned post). The compiler does not read bytecode, it produces it. What reads the bytecode is the JVM.
Don't confuse between defining the methods and using them. Technically you can define both
int foo()
void foo()
But then imagine someone just calls foo()
in his/her code without possibly assigning the return value to a variable. How would the compiler know the call to which method to place in the compiled code?
Why is the return type of method not included in the method-signature?
This is done because the compiler would not be able to figure out the overload in all contexts.
For example, if you call
String x = method1("aaa");
the compiler knows that you are looking for the second overload. However, if you call
method1("aaa");
like this, the compiler has no idea which one of the two methods you wanted to invoke, because it is OK to call a method returning String
and discard the result. To avoid ambiguities like this, Java prohibits overloads that differ solely on the return type.
The relationship of overload and method return type in Java?
consider following points for overloading:
First and important rule to overload a method in java is to change method signature. Method signature is made of number of arguments, type of arguments and order of arguments if they are of different types.
public class DemoClass {
// Overloaded method
public Integer sum(Integer a, Integer b) {
return a + b;
}
// Overloading method
public Integer sum(Float a, Integer b) { //Valid
return null;
}
}Return type of method is never part of method signature, so only changing the return type of method does not amount to method overloading.
public class DemoClass {
// Overloaded method
public Integer sum(Integer a, Integer b) {
return a + b;
}
// Overloading method
public Float sum(Integer a, Integer b) { //Not valid; Compile time error
return null;
}
}Thrown exceptions from methods are also not considered when overloading a method. So your overloaded method throws the same exception, a different exception or it simply does no throw any exception; no effect at all on method loading.
public class DemoClass {
// Overloaded method
public Integer sum(Integer a, Integer b) throws NullPointerException{
return a + b;
}
// Overloading method
public Integer sum(Integer a, Integer b) throws Exception{ //Not valid; Compile time error
return null;
}
}
Related Topics
How to Set Oracle's Java as the Default Java in Ubuntu
How to Encode Uri Parameter Values
Stopping a Window from Displaying Till It Is Fully Drawn
What Java Orm Do You Prefer, and Why
How to Check If a Date Object Equals Yesterday
Calling Jmx Mbean Method from a Shell Script
How to Update a Broadcast Variable in Spark Streaming
In Java, What Are the Boolean "Order of Operations"
If I Synchronized Two Methods on the Same Class, Can They Run Simultaneously
Springboot - Making Jar Files - No Auto Configuration Classes Found in Meta-Inf/Spring.Factories
Java Convert Gmt/Utc to Local Time Doesn't Work as Expected
Java Split Is Eating My Characters
Difference Between Double and Double in Comparison
How to Improve Performance of This Regular Expression Further