Java中的静态与动态绑定
在继续之前需要记住一些关键点,我们将在后面讨论和实现Java中的静态和动态绑定,从而得出差异。
- 私有、最终和静态成员(方法和变量)使用静态绑定,而对于虚拟方法(在Java中方法默认为虚拟),绑定是在运行时基于运行时对象完成的。
- 静态绑定使用类型信息进行绑定,而动态绑定使用对象解析绑定。
- 重载的方法使用静态绑定来解决(决定当有多个同名的方法时调用哪个方法),而重载的方法使用动态绑定,即在运行时。
静态绑定
编译器可以在编译时解析的绑定称为静态绑定或早期绑定。所有静态、私有和最终方法的绑定都是在编译时完成的。
例子:
Java
// Java Program to Illustrate Static Binding
// Main class
class NewClass {
// Static nested inner class
// Class 1
public static class superclass {
// Method of inner class
static void print()
{
// Print statement
System.out.println(
"print() in superclass is called");
}
}
// Static nested inner class
// Class 2
public static class subclass extends superclass {
// Method of inner class
static void print()
{
// print statement
System.out.println(
"print() in subclass is called");
}
}
// Method of main class
// Main driver method
public static void main(String[] args)
{
// Creating objects of static inner classes
// inside main() method
superclass A = new superclass();
superclass B = new subclass();
// Calling method over above objects
A.print();
B.print();
}
}
Java
// Java Program to Illustrate Dynamic Binding
// Main class
public class GFG {
// Static nested inner class
// Class 1
public static class superclass {
// Method of inner class 1
void print()
{
// Print statement
System.out.println(
"print in superclass is called");
}
}
// Static nested inner class
// Class 2
public static class subclass extends superclass {
// Method of inner class 2
@Override void print()
{
// Print statement
System.out.println(
"print in subclass is called");
}
}
// Method inside main class
public static void main(String[] args)
{
// Creating object of inner class 1
// with reference to constructor of super class
superclass A = new superclass();
// Creating object of inner class 1
// with reference to constructor of sub class
superclass B = new subclass();
// Calling print() method over above objects
A.print();
B.print();
}
}
print() in superclass is called
print() in superclass is called
输出说明:如您所见,在这两种情况下都调用了超类的 print 方法。让我们讨论一下这是如何发生的
- 我们使用超类的引用创建了一个子类对象和一个超类对象。
- 由于超类的 print 方法是静态的,编译器知道它不会在子类中被覆盖,因此编译器在编译期间知道要调用哪个 print 方法,因此没有歧义。
作为练习,读者可以将对象 B 的引用更改为子类,然后检查输出。
动态绑定
在动态绑定编译器不决定要调用的方法。覆盖是动态绑定的完美示例。在覆盖父类和子类时具有相同的方法。
例子:
Java
// Java Program to Illustrate Dynamic Binding
// Main class
public class GFG {
// Static nested inner class
// Class 1
public static class superclass {
// Method of inner class 1
void print()
{
// Print statement
System.out.println(
"print in superclass is called");
}
}
// Static nested inner class
// Class 2
public static class subclass extends superclass {
// Method of inner class 2
@Override void print()
{
// Print statement
System.out.println(
"print in subclass is called");
}
}
// Method inside main class
public static void main(String[] args)
{
// Creating object of inner class 1
// with reference to constructor of super class
superclass A = new superclass();
// Creating object of inner class 1
// with reference to constructor of sub class
superclass B = new subclass();
// Calling print() method over above objects
A.print();
B.print();
}
}
print in superclass is called
print in subclass is called
输出说明:这里的输出不同。但为什么?让我们分解代码并彻底理解它。
- 此代码中的方法不是静态的。
- 在编译期间,编译器不知道必须调用哪个 print,因为编译器仅通过引用变量而不是对象类型进行,因此绑定将延迟到运行时,因此相应版本的 print 将是根据对象的类型调用。
Tip: Geeks, now the question arises why binding of static, final, and private methods is always static binding?
Static binding is better performance-wise (no extra overhead is required). The compiler knows that all such methods cannot be overridden and will always be accessed by objects of the local class. Hence compiler doesn’t have any difficulty determining the object of the class (local class for sure). That’s the reason binding for such methods is static.
现在让我们最终看看静态绑定和动态绑定之间的区别如下:Static Binding Dynamic Binding It takes place at compile time for which is referred to as early binding It takes place at runtime so do it is referred to as late binding. It uses overloading more precisely operator overloading method It uses overriding methods. It takes place using normal functions It takes place using virtual functions Real objects never use static binding Real objects use dynamic binding.