内省与反思有什么区别?

U r*_*u s 42 language-agnostic reflection introspection

任何人都可以从语言/环境不可知的角度解释这两个概念之间的区别吗?

还有一组编程语言需要满足的条件才能反思和/或内省吗?

如果有,这些条件是什么?

dec*_*eze 35

维基百科的文章有一个相当不错的总结:

在计算中,类型内省是程序在运行时检查对象的类型或属性的能力.一些编程语言具有此功能.

内省不应该与反射混淆,后者更进一步,是程序在运行时操纵对象的值,元数据,属性和/或函数的能力.一些编程语言,例如Java,也具有该功能.

采用静态类型的编译程序:

SomeType function foo(int i) {
    return new SomeType(i);
}
Run Code Online (Sandbox Code Playgroud)

所有类型都是在编译时已知并强制执行的,如果程序不满足其自己的显式类型约束,则程序甚至不应编译.动态编程语言通常不会表现出这种严格性,变量的类型在编译时不一定是已知的.他们可能看起来更像这样:

function foo(i) {
    return new SomeType(i);
}
Run Code Online (Sandbox Code Playgroud)

该功能无法保证究竟i是什么,它只是通过它.这可能会或可能不会在某处造成问题,类型系统在这里无法提供帮助.然后,这种错误检查通常会降级为userland代码,此类代码需要内省功能:

function foo(i) {
    if (!is_int(i)) {
        throw new InvalidArgumentException;
    }
    return new SomeType(i);
}
Run Code Online (Sandbox Code Playgroud)

究竟要在内省和反思之间划清界线有点值得商榷.有人可能会说内省是允许代码测试什么是什么的东西("我是什么?"),而反射是操纵程序结构本身的能力.例如,一个PHP示例:

$ref = new ReflectionClass('Foo');
$foo = $ref->newInstanceWithoutConstructor();
Run Code Online (Sandbox Code Playgroud)

上面的代码Foo在创建它的新实例时绕过了运行类的构造函数.这是运行时的代码操作.但实际上,PHP中的反射API还包含内省功能.其中一些功能与"较低"内省功能相比可以完成.例如:

$ref = new ReflectionClass($obj);
if ($ref->getName() == 'Foo') ...

if ($obj instanceof Foo) ...
Run Code Online (Sandbox Code Playgroud)

两个片段基本上都做同样的事情,但是一个使用反射,另一个使用所谓的内省.如你所见,几乎没有明确的分界线.然而,反射通常比内省更强大.例如,在PHP中,您必须使用反射API来获取有关函数接受的参数类型的信息.这只是"被动"内省,但属于反射API.这主要是实际实施的问题.

简而言之,根据一般定义,为了内省,程序需要能够在运行时检查自身的部分并基于该信息执行不同的代码.除此之外的反射程序可以在运行时更改其自己的代码执行规则,例如选择不调用构造函数,否则构造函数是语言定义的强制操作.

  • 内省不应与类型内省相混淆.例如,Tcl具有i/o内省,函数源内省,运行时环境内省(可执行文件名,库路径,os,解释器版本等),函数内省(列出所有可用函数),变量内省(列出所有可用变量)等但是没有类型内省,因为tcl:string中只有一种类型. (3认同)

csb*_*blo 10

反射是一种由两种技术组成的机制:

  1. 内省

    程序自我检查的能力

  2. 代祷

    程序修改自身的能力(他的行为或他的状态)

参考 https://fr.wikipedia.org/wiki/R%C3%A9flexion_(informatique)#Introspection_et_intercession

我的参考是法文页,因为英文页没有直接提到代祷这个词。