java - 为什么 getClass().getName() 对未打开的模块类起作用?

标签 java reflection module java-9

我有两个 Java 9 模块、一个服务器和一个处理程序。服务器使用 ServiceLoader 加载 HTTP 处理程序(代码如下)。

为什么此代码段中的 o.getClass().getName() 有效?是因为 provides 将处理程序类打开为反射吗? getClass().getName() 不使用反射吗? Java 是否总是以某种方式将接口(interface)映射到底层类实例(从而映射到类)而不需要反射?

服务器模块代码:

    ServiceLoader
      .load(HTTPHandlerWithContext.class)
      .stream()
      .map(ServiceLoader.Provider::get)
      .forEach(o -> {
        System.out.printf(
          "registering route %s to %s%n",
          o.getContext(),
          o.getClass().getName()
        );
        server.createContext(o.getContext(), o);
      });

处理程序模块信息:

module com.example.helloworld {
  requires com.example.tinyjhttpd;
  requires jdk.httpserver;
  provides com.example.tinyjhttpd.HTTPHandlerWithContext
    with com.example.helloworld.HelloWorld;
}

我认为 Class.java 中的相关片段不足以让我清楚:

    // Cache the name to reduce the number of calls into the VM.
    // This field would be set by VM itself during initClassName call.
    private transient String name;
    private native String initClassName();

最佳答案

Java 语言规范没有详细定义反射(因此,opens 的影响或缺乏反射),而是 refers to the API specification :

[...] This specification constrains the behavior of such classes and interfaces, but does not provide a complete specification for them. The reader is referred to the Java SE Platform API documentation.

Consequently, this specification does not describe reflection in any detail. Many linguistic constructs have analogs in the Core Reflection API (java.lang.reflect) and the Language Model API (javax.lang.model), but these are generally not discussed here.

Java SE Platform API 文档指定何时可以抛出 IllegalAccessException,例如调用Field.getMethod.invoke .

都不是Object.getClass()也不Class.getName()已指定可能抛出 IllegalAccessException

这与引入模块系统之前Java的运行时行为是一致的。只是有关何时授予或不授予访问权限的规则变得更加复杂。

与访问内部数据或调用非 API 方法相比,能够查询类名称的影响相当低。

关于java - 为什么 getClass().getName() 对未打开的模块类起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69064624/

相关文章:

python - windows下无法安装scipy

java - 如何在JPA Spring Boot中的嵌套对象中通过Temporal.TIMESTAMP进行查询?

java - 通过 id 从嵌套对象序列化

c# - 为什么这行得通?

go - 如何在 Golang 中重新输入一个函数?

web-applications - Drupal 模块内部工作的隐喻

node.js - 尝试从 git 安装 npm 模块时出错

java - 教程上的android错误找不到符号变量activity_display_message

java - KeyEvent keyPressed 组合键被阻止

java - 如何从另一个类获取调用者方法的注释