Skip to main content

Choosing the Most Specific Method - Tricky Overloading

Choosing the Most Specific Method - Tricky Method Overloading

Let's start with looking at a code-segment and try to think of the output/error, it would produce when compiled/executed and subsequently we'll discuss the behavior of code.


 public class NullTest {
 
    public static void method(Object obj){
      System.out.println("method with param type - Object");
    }
  
    public static void method(String obj){
      System.out.println("method with param type - String");
    }
  
    public static void main(String [] args){
      method(null);
    }
 }
 
 

So, what do you expect as the output here? Before thinking about the output, do you really expect the code to compile successfully? Well... yeah, the code will compile and run fine as opposed to anyone who might have sensed an ambiguity here - we'll see the reason soon.
Object' or the one with parameter type 'String' and why? Of course, the compiler can't bind two methods with one call, so on what basis would it pick the most suitable? Which method would be picked, is evident from the output given below:-


Since the methods are overloaded, the resolution will be done at compile-time only. Which method do you see being bind here - the one with parameter type '


 method with param type - String
 
 

Any guesses for why a special treatment is being given to '
String' here? Well... it's not actually for 'String' class specifically, but any sub-class would get a preference over the super class in such a situation. But, why? Because JLS (Section: 15.12.2.5) allows this. It clearly says:

"
If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen."

As you easily deduce that the compiler should be able to pick 'the most specific', failing which it will throw a compile-time error. Let's understand it with the below code-segment which doesn't compile because the compiler can't pick 'the most specific' here.


 public class NullTest {
 
    public static void method(Object obj){
      System.out.println("method with param type - Object");
    }
  
    public static void method(String str){
      System.out.println("method with param type - String");
    }
  
    public static void method(StringBuffer strBuf){
      System.out.println("method with param type - StringBuffer");
    }
  
    public static void main(String [] args){
      method(null); //... compile-time error!
    }
 }
 
 

Why is the compiler not able to pick 'the most specific' here - because both
String and StringBuffer are are sub-classes of the Object class, but without being in the same inheritance hierarchy. For finding 'the most specific' method, the compiler needs to find a method having the parameter type, which is a sub-class of the parameter types of all other overloaded methods.

This holds true for overloaded methods having more than one parameters as well. The compiler would pick 'the most specific' by looking which method is having at least one of its parameter types as a clear sub-class of the corresponding parameter type and other parameter types being either the same or clear sub-classes, in all other overloaded methods. If it can find one, good, otherwise it will throw a compile-time error. For example:


 public class NullTest {
 
  public static void method(Object obj, Object obj1){
    System.out.println("method with param types - Object, Object");
  }
 
  public static void method(String str, Object obj){
    System.out.println("method with param types - String, Object");
  }
 
  public static void main(String [] args){
    method(null, null);
  }
 }
 
 Output
 
 method with param types - String, Object
 
 

In this case the compiler can easily pick 'the most specific' as the method having parameter types
(String, Object) as the other overloaded method is having its parameter types as (Object, Object) - clearly 'String' is a subclass of 'Object' and the other parameter is of same type, so the method with parameter types (String, Object) can be picked with ease. But, the below code would throw a compile-time error as none of the methods satisfy the condition for being picked as 'the most specific' method.


 public class NullTest {
 
  public static void method(Object obj, String obj1){
    System.out.println("method with param types - Object, String");
  }
 
  public static void method(String str, Object str1){
    System.out.println("method with param types - String, Object");
  }
 
  public static void main(String [] args){
    method(null, null); //... compile-time error!
  }
 }

Comments

  1. the rules for method overloading resolution in java are very complex. for example, beside the above cases consider the case of an overloaded varargs method.
    for example in this code

    private static void m(Object... elements) {
    System.out.println("1");
    }

    private static void m(Object o) {
    System.out.println("2");
    }

    public static void main(String[] args) {
    m(null);
    }

    which method gets called? it is not trivial from the specification that the first one is more specific unless you treat it as an Object array.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hi ,

    This is Venkat, Your blog is nice and informative, I am having similar blog for Java J2EE Technologies. Please Visit and share your opinion.

    www.java-j2ee-technologies.blogspot.com

    Thanks
    Venkat

    ReplyDelete
  4. Hi..Venkat..thanx for commnets..

    ReplyDelete

Post a Comment

Popular posts from this blog

Asynchronous Vs. Synchronous Communications

Synchronous (One thread):   1 thread -> |<---A---->||<----B---------->||<------C----->| Synchronous (multi-threaded):   thread A -> |<---A---->| \ thread B ------------> ->|<----B---------->| \ thread C ----------------------------------> ->|<------C----->|

WebSphere MQ Interview Questions

What is MQ and what does it do? Ans. MQ stands for MESSAGE QUEUEING. WebSphere MQ allows application programs to use message queuing to participate in message-driven processing. Application programs can communicate across different platforms by using the appropriate message queuing software products. What is Message driven process? Ans . When messages arrive on a queue, they can automatically start an application using triggering. If necessary, the applications can be stopped when the message (or messages) have been processed. What are advantages of the MQ? Ans. 1. Integration. 2. Asynchrony 3. Assured Delivery 4. Scalability. How does it support the Integration? Ans. Because the MQ is independent of the Operating System you use i.e. it may be Windows, Solaris,AIX.It is independent of the protocol (i.e. TCP/IP, LU6.2, SNA, NetBIOS, UDP).It is not required that both the sender and receiver should be running on the same platform What is Asynchrony? Ans. With messag...

Advantages & Disadvantages of Synchronous / Asynchronous Communications?

  Asynchronous Communication Advantages: Requests need not be targeted to specific server. Service need not be available when request is made. No blocking, so resources could be freed.  Could use connectionless protocol Disadvantages: Response times are unpredictable. Error handling usually more complex.  Usually requires connection-oriented protocol.  Harder to design apps Synchronous Communication Advantages: Easy to program Outcome is known immediately  Error recovery easier (usually)  Better real-time response (usually) Disadvantages: Service must be up and ready. Requestor blocks, held resources are “tied up”.  Usually requires connection-oriented protocol