在介绍JPMS服务时,Java语言规范的7.7.4节指出:“服务类型必须是类类型,接口类型或注释类型。”
我很难理解允许注释的意义。我的理解是,服务的JPMS概念是我们希望在运行时为其选择实现的一种东西。同样有用的是,该实现至少需要成为标识请求的服务的原始类之外的其他某种可能性。但是我相信注释不能使用“扩展”,所以这种情况永远不会发生吗?由此,我相信,如果我尝试使用注释类型来提供服务,则不可避免地会遇到这样的情况,即服务查找可能返回的唯一内容是,例如SomeAnnotation。类将完全是SomeAnnotation。这似乎毫无意义,所以我必须假设我错过了一些东西。
任何人都可以阐明这一点,也许提供示例说明注释如何成为“服务”?
答案 0 :(得分:4)
您似乎已经错过了服务提供商的其他成员。在命名模块内,服务提供者可以从静态方法返回实现:
来自
如果服务提供者声明了提供者方法,则服务加载器将调用该方法以获取服务提供者的实例。提供者方法是一个名为“ provider”的公共静态方法,它没有形式参数,并且返回类型可以分配给服务的接口或类。
在这种情况下,服务提供者本身不必分配给服务的接口或类。
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);
}
}
package example;
import java.util.ServiceLoader;
public class ServiceUser {
public static void main(String[] args) {
for(Anno a: ServiceLoader.load(Anno.class)) {
System.out.println(a.value());
}
}
}
答案 1 :(得分:3)
虽然在Java中注解接口无法显式扩展任何接口(但隐式地始终扩展java.lang.annotation.Annotation
),但是可以实现它。即从语法上讲,可以编写一个实现注释接口的具体类,尽管根据JLS 9.6. Annotation Types,此类并不表示注释类型:
注释类型的子类或子接口本身永远不会 注释类型
因此,我认为原始问题可以归结为“ 为什么有人要显式实现注释接口?”。已经在Use cases for implementing annotations中询问并回答了这个问题。那里的公认答案是建议这样做,以部分克服注释元素的值必须是常量表达式,类文字或枚举常量(请参见JLS 9.7.1. Normal Annotations)的局限性:可以实现一个注释接口,用于通过“注释”“注释”实现类,该“注释”包括获取的动态数据,例如显然,这种技术还要求在读取注释的代码中进行 small 更改,因为实现注释接口的类实际上没有注释,但是其实例可以用作注释的实例,就像它被检索到一样通过java.lang.Class.getAnnotationsByType
。