3

In the following program, I have one single method in class A overloaded 3 times and then in subclass B, all 3 overloaded methods are overridden.

obj3 is an object with reference type A(superclass) and object type B(subclass) and it calls the method from B on execution, which is expected behavior.

Since overloading and overriding both exist in this code, does that mean that it performed static binding at compile time (to the matching method in class A) and then dynamic binding at run time (to method in class B). Can they both occur together?

My assumption is that this is a classic case of dynamic binding as I believed "binding" is meant to be a permanent action, but a peer suggests that it is both together(static first, then dynamic).

class A{
    
    public void method(Integer n){
        System.out.println("Integer: "+n);
    }
    
    public void method(String s){
        System.out.println("String: "+s);
    }
    
    public void method(String s, Integer n){
        System.out.println("String: "+s+" Integer: "+n);
    }
}

class B extends A{
    
    public void method(Integer n){
        System.out.println("Integer(from B): "+n);
    }
    
    public void method(String s){
        System.out.println("String(from B): "+s);
    }
    
    public void method(String s, Integer n){
        System.out.println("String(from B): "+s+" Integer(from B): "+n);
    }
}

public class Test{
    public static void main(String[] args){
        A obj1 = new A();
        B obj2 = new B();
        A obj3 = new B();
        
        System.out.println("Integer form of method");
        // Integer form of method

        System.out.println("Ref A Obj A");
        // Ref A Obj A
        obj1.method(1);
        // Integer: 1
        
        System.out.println("Ref B Obj B");
        // Ref B Obj B
        obj2.method(2);
        // Integer(from B): 2
        
        System.out.println("Ref A Obj B");
        // Ref A Obj B
        obj3.method(3);
        // Integer(from B): 3
        
    }
}
kenneth-rebello
  • 914
  • 1
  • 7
  • 13
  • Overloaded methods: compile time (static). Virtual methods: runtime (dynamic). – paulsm4 Sep 02 '20 at 07:19
  • @see https://www.tutorialspoint.com/static-vs-dynamic-binding-in-java – Omid.N Sep 02 '20 at 07:23
  • @paulsm4 well yeah, but as this method is both, overloaded and virtual, I was told by someone that both (static and dynamic) bindings take place, static at compile time and dynamic at runtime. Their argument was that the meaning of "dynamic binding" is that it changes the binding of a static bound method. So in the above example, static binding to method(Integer n) from class A takes place, and then it is dynamically bound to method(Integer n) from class B at runtime which overwrites the previous static binding. Is this true? – kenneth-rebello Sep 02 '20 at 07:28
  • It's not "either or". It's "both". "method(Integer n)" vs "method(String s)", for example, is determined at compile time, based on [arity](https://en.wikipedia.org/wiki/Arity). A.method() vs B.method() is selected dynamically, at runtime. *Both* "decisions" must be made for one of your six methods to be invoked, – paulsm4 Sep 02 '20 at 08:26
  • @paulsm4 Overloaded method resolution is not the same as static binding. Also, static binding methods are said to faster than dynamic binding methods. I think this would prove that once "static binding" has taken place i.e. implementation for a method is decided at compile time, the JVM will not run another check to then again dynamically bind the method, this wouldn't serve the purpose of being faster. Thanks for taking the time to answer but I'm now certain that this case is only dynamic binding. Overloading is only an example of static binding, not a sure way to achieve it. – kenneth-rebello Sep 02 '20 at 10:40
  • 1
    You are correct: overloading is an EXAMPLE of static binding. "static methods" are another example. I never said otherwise :) The IMPORTANT point here is that your code example illustrates BOTH "static" as well as "dynamic" binding in Java. Fortunately, I think you got that :) – paulsm4 Sep 02 '20 at 16:58
  • To @Omid.N I think [tutorialspoint.com/difference-between-static-binding-and-dynamic-binding-in-java](https://www.tutorialspoint.com/difference-between-static-binding-and-dynamic-binding-in-java) is better – Hennadii Kolomoiets Aug 03 '23 at 09:11

3 Answers3

4

You right. Compiler is statically choose between overloads in class A and put that information into .class file in form of method FQN.

Then runtime dynamically choose between implementation of that method.

talex
  • 17,973
  • 3
  • 29
  • 66
4

Since overloading and overriding both exist in this code, does that mean that it performed static binding at compile time (to the matching method in class A) and then dynamic binding at run time (to method in class B)

Right. The compiler chose the matching signature, and this is static, based on the type of the variable (A in this case).

At runtime, Java finds the implementation of the signature selected by the compiler. This is dynamic, based on the runtime class of obj3 (B, in this case).

ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • is matching the signature considered to be same as binding. Sorry but I'm a little new to the various terminologies, but what I figured was binding meant binding to a function implementation. This should only be possible in the case of private, static and final methods, right? Wouldn't that mean this is **only** dynamically bound to `method` in class `B`. – kenneth-rebello Sep 02 '20 at 07:57
  • Let me first understand the core of your question... Is it primarily related to your *"I was told by someone that both (static and dynamic) bindings take place, static at compile time and dynamic at runtime"* comment (about the *public* instance method)? – ernest_k Sep 02 '20 at 08:18
  • Yes that's correct. My doubt arises from the idea (might be wrong) that binding is a one time thing. So a method call must be bound to one single method implementation. This is based on the fact that static binding is related to private, static and final methods (all of which are pretty straightforward cases of why they come under static binding examples). How overloading is related to static binding is what is confusing me. I agree that the compiler will select one method signature from A, but it still can't determine an implementation, so I assumed that wouldn't be called binding. – kenneth-rebello Sep 02 '20 at 09:52
  • @kenneth-rebello My understanding (and I could be wrong) is that both are part of binding. It starts with overload resolution where applicable and includes implementation selection. Statically, the compiler resolves overloads and proceeds to determining the implementation where it can (the cases you listed: private, static, etc.). Dynamically, the runtime picks the implementation for other cases (although overload resolution only happens at compile time). I see the nuance, but I've always seen both included in binding. – ernest_k Sep 02 '20 at 10:13
  • Yes overloading can definitely be used as an example for static binding. I still maintain that it's not a sure shot case though. Anyway, appreciate you taking the time to answer! – kenneth-rebello Sep 02 '20 at 10:33
0

One more attempt to make it clear:

Overloading

Overloading means that a single class has multiple methods with different parameter types (aka. signatures), and you just happened to give them the same name. Your program will work the very same if you change to individual names for the methods, e.g. methodI(Integer n), methodS(String s), and methodSI(String s, Integer n).

Or, you can imagine the compiler to internally always append such a types list to the method name.

Overloading is resolved by the compiler, based on the compile-time types of the parameter expressions.

E.g. if you write

Object par = "Test";
a.method(par);

you get a compiler error. Even though we all see it's a String that you are passing into the method, the compiler only sees an Object, and finds no matching method. Only if you were to introduce an additional method(Object o), the compiler would choose that one. And runtime would call that method and not the String version!

Overriding

Overriding means that at runtime the JVM calls the method implementation depending on the runtime class of the "object before the dot".

And in this case, "method" is to be read as the overloaded method version that the compiler found to match the parameter list. So, runtime already knows whether methodI(), methodS(), or methodSI() is meant, and only decides from which class to take the implementation.

Personal opinion

Allowing multiple methods to share the same name, but differ in parameter lists (aka overloading), produces too much confusion for its benefit.

Ralf Kleberhoff
  • 6,990
  • 1
  • 13
  • 7