静态VS. Java中的dynamic绑定
我目前正在为我的一个类做一个任务,在这个过程中,我必须给出使用Java语法的静态和dynamic绑定的例子。
我理解的基本概念,即静态绑定发生在编译时,dynamic绑定发生在运行时,但我不明白他们是如何实际工作的具体。
我发现一个在线的静态绑定的例子,给出了这个例子:
public static void callEat(Animal animal) { System.out.println("Animal is eating"); } public static void callEat(Dog dog) { System.out.println("Dog is eating"); } public static void main(String args[]) { Animal a = new Dog(); callEat(a); }
而这将打印“动物正在吃”,因为callEat
的调用使用静态绑定 ,但我不确定为什么这被认为是静态绑定。
到目前为止,我所看到的所有消息都没有以我可以遵循的方式解释这一点。
来自: http : //javarevisited.blogspot.com/2012/03/what-is-static-and-dynamic-binding-in.html
这里有几个静态和dynamic绑定的重要区别
1)Java中的静态绑定发生在编译期间,而dynamic绑定发生在运行期间。
2)私有的,最终的和静态的方法和variables使用静态绑定和编译器绑定,而虚拟方法在运行时基于运行时对象绑定。
3)静态绑定使用Type(Class in Java)信息进行绑定,Dynamic binding使用Object来parsing绑定。
3)重载方法使用静态绑定绑定,而重写的方法在运行时使用dynamic绑定绑定。
这里有个例子可以帮助你理解Java中的静态和dynamic绑定。
Java中的静态绑定示例
public class StaticBindingTest { public static void main(String args[]) { Collection c = new HashSet(); StaticBindingTest et = new StaticBindingTest(); et.sort(c); } //overloaded method takes Collection argument public Collection sort(Collection c) { System.out.println("Inside Collection sort method"); return c; } //another overloaded method which takes HashSet argument which is sub class public Collection sort(HashSet hs) { System.out.println("Inside HashSet sort method"); return hs; } }
输出:内部收集sorting方法
Java中的dynamic绑定示例
public class DynamicBindingTest { public static void main(String args[]) { Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car vehicle.start(); //Car's start called because start() is overridden method } } class Vehicle { public void start() { System.out.println("Inside start method of Vehicle"); } } class Car extends Vehicle { @Override public void start() { System.out.println("Inside start method of Car"); } }
输出:Car的内部启动方法
将方法调用连接到方法体称为绑定。 正如Maulik所说:“静态绑定使用Type(Java中的Class)信息进行绑定,而dynamic绑定使用Object来parsing绑定”。 所以这个代码:
public class Animal { void eat() { System.out.println("animal is eating..."); } } class Dog extends Animal { public static void main(String args[]) { Animal a = new Dog(); a.eat(); // prints >> dog is eating... } @Override void eat() { System.out.println("dog is eating..."); } }
会产生结果: 狗正在吃…因为它使用对象引用来find使用哪种方法。 如果我们将上面的代码更改为:
class Animal { static void eat() { System.out.println("animal is eating..."); } } class Dog extends Animal { public static void main(String args[]) { Animal a = new Dog(); a.eat(); // prints >> animal is eating... } static void eat() { System.out.println("dog is eating..."); } }
它会产生: 动物正在吃…因为它是一个静态的方法,所以它使用Type(在这种情况下动物)来解决调用哪个静态方法。 除了静态方法,private和final方法使用相同的方法。
编译器只知道“a”的types是Animal
; 这发生在编译时,因为它被称为静态绑定(方法重载)。 但是,如果它是dynamic绑定,那么它会调用Dog
类的方法。 这里是一个dynamic绑定的例子。
public class DynamicBindingTest { public static void main(String args[]) { Animal a= new Dog(); //here Type is Animal but object will be Dog a.eat(); //Dog's eat called because eat() is overridden method } } class Animal { public void eat() { System.out.println("Inside eat method of Animal"); } } class Dog extends Animal { @Override public void eat() { System.out.println("Inside eat method of Dog"); } }
输出:狗的内部吃法
在devise编译器时,静态和dynamic绑定有三个主要区别, variables和过程如何转换到运行时环境。 这些差异如下:
静态绑定 :在静态绑定中,讨论了以下三个问题:
-
定义一个程序
-
名称声明(variables等)
-
声明的范围
dynamic绑定 : dynamic绑定中遇到的三个问题如下:
-
激活一个程序
-
绑定一个名字
-
一个绑定的生命周期
让我们讨论Java中静态和dynamic绑定的区别。
静态绑定发生在编译时,而dynamic绑定发生在运行时。
私有,静态和最终方法的绑定总是发生在编译时,因为这些方法不能被覆盖。 重写的方法的绑定发生在运行时。
Java对重载的方法使用静态绑定,对重写的方法使用dynamic绑定。
因为编译器在编译时知道绑定。 例如,如果您在一个接口上调用一个方法,那么编译器无法知道,并且绑定在运行时被parsing,因为调用该方法的实际对象可能是其中的一个。 因此,这是运行时或dynamic绑定。
您的调用在编译时绑定到Animal类,因为您已经指定了types。 如果你将这个variables传递给其他地方的另一个方法,没有人会知道(除了你之外,因为你写了它)什么样的实际类。 唯一的线索是动物的声明types。