有没有人能够从语言和环境的角度解释这两个概念之间的区别?
另外,编程语言需要满足一组条件才能成为反射性和/或内省性吗?
如果有这样的条件,那么这些条件是什么?
有没有人能够从语言和环境的角度解释这两个概念之间的区别?
另外,编程语言需要满足一组条件才能成为反射性和/或内省性吗?
如果有这样的条件,那么这些条件是什么?
维基百科文章中有一个相当不错的概述:
在计算机科学中,类型内省是指程序在运行时检查对象类型或属性的能力。一些编程语言具备这种能力。
内省不应与反射混淆,后者更进一步,也就是程序能够在运行时操作对象的值、元数据、属性和/或函数的能力。一些编程语言,例如Java,也具备这种能力。
以静态类型、编译型程序为例:
SomeType function foo(int i) {
return new SomeType(i);
}
所有类型都在编译时已知和强制执行,如果程序不满足其自己的显式类型约束,则程序甚至不应该编译。动态编程语言通常不表现出这种严格性,变量的类型不一定在编译时就已知。它们可能看起来更像这样:function foo(i) {
return new SomeType(i);
}
这个函数无法保证 i
是准确的,它只是传递它。这可能会导致某些问题,类型系统也无法帮助解决。这种错误检查通常由用户代码处理,因此需要具有内省能力的代码:
function foo(i) {
if (!is_int(i)) {
throw new InvalidArgumentException;
}
return new SomeType(i);
}
如何准确地界定内省(introspection)与反射(reflection)之间的区别存在一些争议。有人认为,内省是指任何允许代码测试某个东西是什么(“我是什么?”)的行为,而反射则是指能够操作程序结构本身的能力。例如,PHP 的一个示例:
$ref = new ReflectionClass('Foo');
$foo = $ref->newInstanceWithoutConstructor();
上述代码规避了创建新实例时运行Foo
类的构造函数。这是运行时代码操作。不过,在实践中,PHP反射API还包含内省能力。其中一些能力是“较低级”内省能力所能做到的重复功能。例如:
以上代码绕过了创建一个新实例时运行Foo
类的构造函数。这是运行时的代码操作。但在实践中,PHP的反射API也包含了内省的功能。其中一些能力与“更低级”的内省能力可以完成相同的任务。例如:
$ref = new ReflectionClass($obj);
if ($ref->getName() == 'Foo') ...
if ($obj instanceof Foo) ...
这两个代码片段本质上都做着相同的事情,但一个使用了反射(reflection),另一个则可称作内省(introspection)。可以看出,二者之间很难有清晰的分界线。不过,通常情况下,反射要比内省更加强大。例如在PHP中,你必须使用反射API来获取函数接受参数的类型信息,这只是“被动”的内省但属于反射API。不过这主要是实际实现的问题。
简而言之,按照一般定义,一个具有内省能力的程序需要能够在运行时检查其自身的部分,并根据此信息执行不同的代码。而一个拥有反射能力的程序除此之外还能在运行时改变自己的代码执行规则,例如选择不调用构造函数,而这在语言定义中通常是必需的操作。
反射是由两种技术组成的机制:
内省
程序自我检查的能力
干预
程序修改自身(行为或状态)的能力
参考资料:https://fr.wikipedia.org/wiki/R%C3%A9flexion_(informatique)#Introspection_et_intercession
我的参考资料是法语页面,因为英语页面没有直接涉及到“intercession”术语。
编程语言在运行时检查对象类型或属性的能力。
示例(Java):
String myObj1 = new String();
MyCustomObject myObj2 = new MyCustomObject();
if(myObj2 instanceof MyCustomObject) {
System.out.println("This is an example of type interospection");
}
编程语言在运行时实现以下功能的能力。