search
HomeJavajavaTutorialDetailed introduction to static binding and dynamic binding in Java

The execution of a Java program requires two steps: compilation and execution (interpretation). At the same time, Java is an object-oriented programming language. When the subclass and the parent class have the same method, and the subclass overrides the method of the parent class, when the program calls the method at runtime, should it call the method of the parent class or the overridden method of the subclass? This should be the question when we first learn Java. problems encountered. Here first we will determine which method to call or the operation of variables is called binding.

There are two binding methods in Java, one is static binding, also called early binding. The other is dynamic binding, also known as late binding.

Difference comparison

1. Static binding occurs at compile time, dynamic binding occurs at runtime
2. Use variables or methods modified with private or static or final, use static Binding. Virtual methods (methods that can be overridden by subclasses) will be dynamically bound according to the runtime object.
3. Static binding is completed using class information, while dynamic binding needs to be completed using object information.
4. The overloaded method is completed using static binding, while the overriding method is completed using dynamic binding.

Example of overloaded method

Here is an example of overloaded method.

public class TestMain {
  public static void main(String[] args) {
      String str = new String();
      Caller caller = new Caller();
      caller.call(str);
  }
  static class Caller {
      public void call(Object obj) {
          System.out.println("an Object instance in Caller");
      }
      
      public void call(String str) {
          System.out.println("a String instance in in Caller");
      }
  }
}

The execution result is

22:19 $ java TestMain
a String instance in in Caller

In the above code, there are two overloaded implementations of the call method. One receives an object of type Object as a parameter, and the other receives String. Object of type as parameter. str is a String object, and all call methods that receive String type parameters will be called. The binding here is static binding based on the parameter type at compile time.

Verification

Just looking at the appearance cannot prove that static binding is performed. You can verify it by using javap to compile it.

22:19 $ javap -c TestMain
Compiled from "TestMain.java"
public class TestMain {
  public TestMain();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/lang/String
       3: dup
       4: invokespecial #3                  // Method java/lang/String."<init>":()V
       7: astore_1
       8: new           #4                  // class TestMain$Caller
      11: dup
      12: invokespecial #5                  // Method TestMain$Caller."<init>":()V
      15: astore_2
      16: aload_2
      17: aload_1
      18: invokevirtual #6                  // Method TestMain$Caller.call:(Ljava/lang/String;)V
      21: return
}

saw this line 18: invokevirtual #6 // Method TestMain$Caller.call:(Ljava/lang/String;)V is indeed statically bound, and it is confirmed that the call receives the String object as Parameter caller method.

Example of overriding method

public class TestMain {
  public static void main(String[] args) {
      String str = new String();
      Caller caller = new SubCaller();
      caller.call(str);
  }
  
  static class Caller {
      public void call(String str) {
          System.out.println("a String instance in Caller");
      }
  }
  
  static class SubCaller extends Caller {
      @Override
      public void call(String str) {
          System.out.println("a String instance in SubCaller");
      }
  }
}

The execution result is

22:27 $ java TestMain
a String instance in SubCaller

The above code has an implementation of the call method in Caller. SubCaller inherits Caller and rewrites it. The implementation of the call method. We declared a variable callerSub of type Caller, but this variable points to a SubCaller object. According to the results, it can be seen that it calls the call method implementation of SubCaller instead of the call method of Caller. The reason for this result is that dynamic binding occurs at runtime, and during the binding process it is necessary to determine which version of the call method implementation to call.

Verification

Dynamic binding cannot be directly verified using javap. If it is proved that static binding is not performed, it means that dynamic binding is performed.

22:27 $ javap -c TestMain
Compiled from "TestMain.java"
public class TestMain {
  public TestMain();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/lang/String
       3: dup
       4: invokespecial #3                  // Method java/lang/String."<init>":()V
       7: astore_1
       8: new           #4                  // class TestMain$SubCaller
      11: dup
      12: invokespecial #5                  // Method TestMain$SubCaller."<init>":()V
      15: astore_2
      16: aload_2
      17: aload_1
      18: invokevirtual #6                  // Method TestMain$Caller.call:(Ljava/lang/String;)V
      21: return
}

As the above result, 18: invokevirtual #6 // Method TestMain$Caller.call:(Ljava/lang/String;)V Here is TestMain$Caller.call instead of TestMain$SubCaller.call, Because the compile time cannot determine whether to call the implementation of the subclass or the parent class, it can only be left to the dynamic binding at runtime.

When overloading meets overriding

The following example is a bit abnormal. There are two overloads of the call method in the Caller class. What is more complicated is that SubCaller integrates Caller and rewrites this Two methods. In fact, this situation is a compound situation of the above two situations.

The following code will first be statically bound to determine the call method whose parameter is a String object, and then dynamically bound at runtime to determine whether to execute the call implementation of the subclass or the parent class.

public class TestMain {
  public static void main(String[] args) {
      String str = new String();
      Caller callerSub = new SubCaller();
      callerSub.call(str);
  }
  
  static class Caller {
      public void call(Object obj) {
          System.out.println("an Object instance in Caller");
      }
      
      public void call(String str) {
          System.out.println("a String instance in in Caller");
      }
  }
  
  static class SubCaller extends Caller {
      @Override
      public void call(Object obj) {
          System.out.println("an Object instance in SubCaller");
      }
      
      @Override
      public void call(String str) {
          System.out.println("a String instance in in SubCaller");
      }
  }
}

The execution result is

22:30 $ java TestMain
a String instance in in SubCaller

Verification

Since it has been introduced above, I will only post the decompilation result here

22:30 $ javap -c TestMain
Compiled from "TestMain.java"
public class TestMain {
  public TestMain();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/lang/String
       3: dup
       4: invokespecial #3                  // Method java/lang/String."<init>":()V
       7: astore_1
       8: new           #4                  // class TestMain$SubCaller
      11: dup
      12: invokespecial #5                  // Method TestMain$SubCaller."<init>":()V
      15: astore_2
      16: aload_2
      17: aload_1
      18: invokevirtual #6                  // Method TestMain$Caller.call:(Ljava/lang/String;)V
      21: return
}

Curious questions

Isn’t it possible to have dynamic binding?

In fact, theoretically, the binding of certain methods can also be achieved by static binding. For example:

public static void main(String[] args) {
      String str = new String();
      final Caller callerSub = new SubCaller();
      callerSub.call(str);
}

For example, here callerSub holds the object of subCaller and the callerSub variable is final, and the call method is executed immediately. In theory, the compiler can know that the call method of SubCaller should be called by sufficient analysis of the code.

But why is there no static binding?
Assume that our Caller inherits from the BaseCaller class of a certain framework, which implements the call method, and BaseCaller inherits from SuperCaller. The call method is also implemented in SuperCaller.

Suppose BaseCaller and SuperCaller in a certain framework 1.0

static class SuperCaller {
  public void call(Object obj) {
      System.out.println("an Object instance in SuperCaller");
  }
}
  
static class BaseCaller extends SuperCaller {
  public void call(Object obj) {
      System.out.println("an Object instance in BaseCaller");
  }
}

and we use framework 1.0 to implement this. Caller inherits from BaseCaller and calls the super.call method.

public class TestMain {
  public static void main(String[] args) {
      Object obj = new Object();
      SuperCaller callerSub = new SubCaller();
      callerSub.call(obj);
  }
  
  static class Caller extends BaseCaller{
      public void call(Object obj) {
          System.out.println("an Object instance in Caller");
          super.call(obj);
      }
      
      public void call(String str) {
          System.out.println("a String instance in in Caller");
      }
  }
  
  static class SubCaller extends Caller {
      @Override
      public void call(Object obj) {
          System.out.println("an Object instance in SubCaller");
      }
      
      @Override
      public void call(String str) {
          System.out.println("a String instance in in SubCaller");
      }
  }
}

Then we compiled the class file based on version 1.0 of this framework. Assuming that static binding can determine that the super.call of the above Caller is implemented as BaseCaller.call.

Then we again assume that BaseCaller does not rewrite the call method of SuperCaller in version 1.1 of this framework. Then the above assumption that the call implementation that can be statically bound will cause problems in version 1.1, because in version 1.1 super. The call should be implemented using the call method of SuperCall, rather than the call method of BaseCaller determined by static binding.

So, some things that can actually be bound statically are simply bound dynamically in consideration of security and consistency.

Optimization inspiration obtained?

Because dynamic binding needs to determine which version of the method implementation or variable to execute at runtime, it is more time-consuming than static binding.

So without affecting the overall design, we can consider modifying methods or variables with private, static or final.

For more detailed introduction to static binding and dynamic binding in Java, please pay attention to the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Is Java Platform Independent if then how?Is Java Platform Independent if then how?May 09, 2025 am 12:11 AM

Java is platform-independent because of its "write once, run everywhere" design philosophy, which relies on Java virtual machines (JVMs) and bytecode. 1) Java code is compiled into bytecode, interpreted by the JVM or compiled on the fly locally. 2) Pay attention to library dependencies, performance differences and environment configuration. 3) Using standard libraries, cross-platform testing and version management is the best practice to ensure platform independence.

The Truth About Java's Platform Independence: Is It Really That Simple?The Truth About Java's Platform Independence: Is It Really That Simple?May 09, 2025 am 12:10 AM

Java'splatformindependenceisnotsimple;itinvolvescomplexities.1)JVMcompatibilitymustbeensuredacrossplatforms.2)Nativelibrariesandsystemcallsneedcarefulhandling.3)Dependenciesandlibrariesrequirecross-platformcompatibility.4)Performanceoptimizationacros

Java Platform Independence: Advantages for web applicationsJava Platform Independence: Advantages for web applicationsMay 09, 2025 am 12:08 AM

Java'splatformindependencebenefitswebapplicationsbyallowingcodetorunonanysystemwithaJVM,simplifyingdeploymentandscaling.Itenables:1)easydeploymentacrossdifferentservers,2)seamlessscalingacrosscloudplatforms,and3)consistentdevelopmenttodeploymentproce

JVM Explained: A Comprehensive Guide to the Java Virtual MachineJVM Explained: A Comprehensive Guide to the Java Virtual MachineMay 09, 2025 am 12:04 AM

TheJVMistheruntimeenvironmentforexecutingJavabytecode,crucialforJava's"writeonce,runanywhere"capability.Itmanagesmemory,executesthreads,andensuressecurity,makingitessentialforJavadeveloperstounderstandforefficientandrobustapplicationdevelop

Key Features of Java: Why It Remains a Top Programming LanguageKey Features of Java: Why It Remains a Top Programming LanguageMay 09, 2025 am 12:04 AM

Javaremainsatopchoicefordevelopersduetoitsplatformindependence,object-orienteddesign,strongtyping,automaticmemorymanagement,andcomprehensivestandardlibrary.ThesefeaturesmakeJavaversatileandpowerful,suitableforawiderangeofapplications,despitesomechall

Java Platform Independence: What does it mean for developers?Java Platform Independence: What does it mean for developers?May 08, 2025 am 12:27 AM

Java'splatformindependencemeansdeveloperscanwritecodeonceandrunitonanydevicewithoutrecompiling.ThisisachievedthroughtheJavaVirtualMachine(JVM),whichtranslatesbytecodeintomachine-specificinstructions,allowinguniversalcompatibilityacrossplatforms.Howev

How to set up JVM for first usage?How to set up JVM for first usage?May 08, 2025 am 12:21 AM

To set up the JVM, you need to follow the following steps: 1) Download and install the JDK, 2) Set environment variables, 3) Verify the installation, 4) Set the IDE, 5) Test the runner program. Setting up a JVM is not just about making it work, it also involves optimizing memory allocation, garbage collection, performance tuning, and error handling to ensure optimal operation.

How can I check Java platform independence for my product?How can I check Java platform independence for my product?May 08, 2025 am 12:12 AM

ToensureJavaplatformindependence,followthesesteps:1)CompileandrunyourapplicationonmultipleplatformsusingdifferentOSandJVMversions.2)UtilizeCI/CDpipelineslikeJenkinsorGitHubActionsforautomatedcross-platformtesting.3)Usecross-platformtestingframeworkss

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version