名字绑定

程式設計語言中,名字绑定是把实体(数据或/且代码)关联到标识符[1]标识符绑定到实体被称为引用该对象。机器语言没有内建的标识符表示方法,但程序设计语言实现了名字与对象的绑定。绑定最初是与作用域相关,因为作用域确定了哪个名字绑定到哪个对象——在程序代码中的哪个位置与哪条执行路径。

绑定时机

  • 静态绑定(Static binding)或称早绑定(early binding):名字绑定发生在程序开始运行之前。[2]
  • 动态绑定(Dynamic binding)或称迟绑定(late binding)、虚绑定(virtual binding):名字绑定发生在程序运行时。[2]

静态绑定的例子,如C语言的函数调用:用标识符引用的函数在运行时不能改变。

动态绑定的例子如C++虚函数调用时的动态分派。由于多态对象的具体类型在运行前是未知的,因此被执行函数需要动态绑定。

public void foo(java.util.List<String> list) {
    list.add("bar");
}

List是一个接口,因此list必须引用到它的子类型。它是引用到LinkedListArrayListList的其它子类型add实际引用到的方法在运行时之前也是未知的。C语言中,这种动态绑定可以通过调用一个函数指针类型的变量或表达式,其值直到运行时求值之前都是未知的。

重绑定与变异

重绑定不能与变异混淆:

  • 重绑定(Rebinding)是改变引用的标识符;
  • 变异(Mutation)是改变被引用的实体。

考虑下面Java代码:

LinkedList<String> list;
list = new LinkedList<String>();
list.add("foo");
list = null;

标识符list最初引用到空(未初始化英语uninitialized variable);然后重绑定到一个对象(一个字符串链表);这个被list引用的字符串链表被变异,即增加一个字符串到该链表;最后,list被重绑定到null

静态迟绑定

静态迟绑定(late static binding)是静态绑定与动态绑定之间的一个变种。考虑下述PHP例子:

class A
{
    static $word = "hello";
    static function hello() { print self::$word; }
}

class B extends A
{
    static $word = "bye";
}

B::hello();

在上例中,PHP解释器把A::hello()关键字self绑定到类A,因此B::hello()打印出字符串"hello"。如果self::$word的语义是基于静态迟绑定,结果就是"bye"。

从PHP版本5.3开始支持静态迟绑定。[3]具体说,上例中的self::$word如果改为下例中的static::$word,关键字static指示运行时才绑定,B::hello()的调用结果将是"bye":

class A
{
    static $word = "hello";
    static function hello() { print static::$word; }
}

class B extends A
{
    static $word = "bye";
}

B::hello();

参见

参考文献

  1. ^ Microsoft, Using early binding and late binding in Automation, Microsoft, May 11, 2007 [May 11, 2009], (原始内容存档于2015-02-22) 
  2. ^ 2.0 2.1 Systems and software engineering — Vocabulary ISO/IEC/IEEE 24765:2010(E), IEEE, Dec 15, 2010 
  3. ^ Late Static Bindings. [July 3, 2013]. (原始内容存档于2019-02-21).