JPMS为什么允许注释类型作为服务

问题描述 投票:6回答:2

[在引入JPMS服务时,Java语言规范的7.7.4节指出,“服务类型必须是类类型,接口类型或注释类型。”

我正在努力查看允许注释的意义。我的理解是,服务的JPMS概念是我们希望在运行时为其选择实现的一种东西。同样有用的是,该实现至少需要成为标识请求的服务的原始类之外的其他某种可能性。但是我相信注释不能使用“扩展”,所以这种情况永远不会发生吗?由此,我相信,如果我尝试使用注释类型来提供服务,则不可避免地会遇到这样的情况,即服务查找可能返回的唯一内容是,例如SomeAnnotation。类将完全是SomeAnnotation。这似乎毫无意义,所以我必须假设我缺少什么。

任何人都可以阐明这一点,也许可以提供有关注释可能是“服务”的示例?

java java-9 java-module java-annotations
2个回答
3
投票

虽然在Java中注解接口不能显式扩展任何接口(但隐式地始终扩展java.lang.annotation.Annotation),但是可以实现它。即从语法上讲,可以编写一个实现注释接口的具体类,尽管根据JLS 9.6. Annotation Types,此类并不表示注释类型:

注解类型的子类或子接口本身从不注释类型

因此,我认为原始问题归结为“ 为什么有人要显式实现注释接口?。在SO上已经提出并回答了这个问题:Use cases for implementing annotations。那里的公认答案是建议这样做,以部分克服注释元素的值必须是常量表达式,类文字或枚举常量(请参见JLS 9.7.1. Normal Annotations)的局限性:可以实现注释接口以“注释”“注释”实现类的接口,该“注释”包括获取的动态数据,例如显然,由于实现注释接口的类实际上并未注释,因此,该技术还需要在读取注释的代码中进行small更改,而可以将其实例用作注释的实例,就好像它已被检索到一样通过java.lang.Class.getAnnotationsByType


3
投票

似乎您已经错过了服务提供商的另一项新增功能。在命名模块内,服务提供者可以从静态方法返回实现:

  • 如果服务提供者声明了提供者方法,则服务加载器将调用该方法以获取服务提供者的实例。提供者方法是一个名为“ provider”的公共静态方法,它没有形式参数,并且返回类型可以分配给服务的接口或类。

    在这种情况下,不需要将服务提供者本身分配给服务的接口或类。

来自ServiceLoader

因此,以下将起作用:

ServiceLoader
module Example.Module {
    uses example.Anno;
    provides example.Anno with example.AnnoProvider;
}
package example;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface Anno {
    int value();
}
package example;

@Anno(42)
public class AnnoProvider {
    public static Anno provider() {
        return AnnoProvider.class.getAnnotation(Anno.class);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.