Reflection 内省和反思有什么区别?

Reflection 内省和反思有什么区别?,reflection,language-agnostic,introspection,Reflection,Language Agnostic,Introspection,有人能从语言/环境不可知论的角度解释这两个概念之间的区别吗 编程语言是否需要满足一组条件才能进行反射和/或内省 如果有,这些条件是什么?有一个相当不错的总结: 在计算中,类型内省是程序在运行时检查对象类型或属性的能力。有些编程语言具有这种能力 内省不应与反射混淆,后者更进一步,是程序在运行时操纵对象的值、元数据、属性和/或功能的能力。一些编程语言,例如Java,也具有这种能力 以静态类型的编译程序为例: SomeType function foo(int i) { return new

有人能从语言/环境不可知论的角度解释这两个概念之间的区别吗

编程语言是否需要满足一组条件才能进行反射和/或内省

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

有一个相当不错的总结:

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


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

以静态类型的编译程序为例:

SomeType function foo(int i) {
    return new SomeType(i);
}
所有类型都是已知的,并且在编译时强制执行,如果程序不满足自己的显式类型约束,它甚至不应该编译。动态编程语言通常不会表现出这种刚性,在编译时不一定知道变量的类型。它们可能看起来更像这样:

function foo(i) {
    return new SomeType(i);
}
函数不能保证
i
是什么,它只是通过它传递。这可能会也可能不会在某个地方导致问题,类型系统在这里无能为力。这种类型的错误检查通常被降级到userland代码,对于这类代码,需要自省功能:

function foo(i) {
    if (!is_int(i)) {
        throw new InvalidArgumentException;
    }
    return new SomeType(i);
}
内省和反思之间的界限究竟在哪里有点争议。有人可能会说,内省是允许代码测试某事物的任何东西(“我是什么?”),而反射是操纵程序结构本身的能力。例如,一个PHP示例:

$ref = new ReflectionClass('Foo');
$foo = $ref->newInstanceWithoutConstructor();
在创建类的新实例时,上述代码避免了运行类
Foo
的构造函数。这是运行时的代码操作。但实际上,PHP中的反射API也包含内省功能。其中一些功能是“较低”内省功能的重复。例如:

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

if ($obj instanceof Foo) ...
这两个代码片段基本上做相同的事情,但其中一个使用反射,另一个使用内省。正如你所看到的,几乎没有一条清晰的分界线。然而,反思通常比内省更强大。例如,在PHP中,必须使用反射API来获取有关函数接受的参数类型的信息。这只是“被动”的内省,但属于反射API。不过,这主要是一个实际实施的问题

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

类型内省: 编程语言在运行时检查对象类型或属性的能力

示例(Java):


反思: 编程语言在运行时实现以下功能的能力

  • 类型内省(如上所示)
  • 检查和修改对象
  • 还有更多

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

  • 内省

    程序检查自身的能力

  • 调解

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

  • 参考文献


    我的参考文献是一个法语页面,因为英语页面没有直接提到“调解”一词。

    只需点击你在这个问题上提出的标签的标签wiki,这是一个很好的起点。不?是的,但它没有说任何关于一般情况的问题。有趣的是,这个相关的问题提供了一个很好的答案:内省不应该与类型内省混淆。例如,Tcl有i/o内省、函数源内省、运行时环境内省(可执行文件名称、库路径、操作系统、解释器版本等)、函数内省(列出所有可用函数)、变量内省(列出所有可用变量)等等,但是没有类型内省,因为tcl中只有一种类型:string。很公平,我改变了措辞。反射如何修改类结构?请参见此处:。
    String myObj1 = new String();
    MyCustomObject myObj2 = new MyCustomObject();
    if(myObj2 instanceof MyCustomObject) {
        System.out.println("This is an example of type interospection");
    }