首页 > 解决方案 > 为什么java注解语法有()[括号]?

问题描述

为什么在“java”中,当您声明“注释”的“参数”时,您必须在参数之后放置“一对括号”,注释无论如何在语法上与“接口”形式“非常不同”,所以为什么这种奇怪的语法.. .我知道这有关系,注释是在幕后使用接口管理的,但究竟是什么?

标签: javaannotations

解决方案


这是一个普通的接口声明的样子:

public interface Example {
    String method();
}

请注意,当注释发布时,Java 功能“接口的默认方法”还没有出现。default关键字已经存在(并且自 java 1.0 以来就存在),仅作为您可以放在 switch 块中的东西,作为“它不匹配任何案例”的“案例” 。

这是注解接口定义的样子:

public @interface Example {
    String method();
}

或者,如果涉及默认值:

public @interface Example {
    String method() default "";
}

请注意,除了“@”符号之外,这两者之间的解析方式没有区别。在“默认”情况下;是的,这是全新的,但仅看那一点,看起来并不奇怪。括号是,但不是那么一点。

这样做的原因是不“爆炸”解析。由于在 java9 中引入了 module-info,如果你想为 java 编写一个解析器,你通常需要一个“动态切换模式”解析器;模块文件的“语言规范”非常不同。

但这是一大步;绝大多数解析器库都不能很好地处理这个问题,它们无法在解析源文件的过程中切换语法。

即使我可以打响指并破坏 java(需要明确的是,java 通常不会这样做:更新语言以使现有代码现在不再编译或意味着其他东西是一个很大的步骤,由于明显的原因很少采取. 但是它限制了语言设计。这是成为世界上最受欢迎的语言的代价*)......这里有优势。

注释的工作方式是,如果您在运行时获得一个,它就像一个对象,是注释接口的一个实例:

Example foo = Class.forName("foo.bar.Baz").getAnnotation(Example.class);
System.out.println(foo.method());

请注意它不是foo.method。是foo.method()。这有不同的原因:在 java 中,字段是二流公民。你不能把它们放在 lambda 方法引用中(ClassName::methodName是有效的 java;字段没有这样的东西),它们不继承,你不能把它们放在接口中(接口中的字段自动是公共的、最终的和静态的,即常量。与接口中的方法不同,它们不会要求任何实现类)。这意味着作为一般原则点的字段不用于 java 的公共 API。如果在这种情况下会是这样,那就太奇怪了。

因此,鉴于参数的行为类似于无参数方法调用,从这个意义上说,您在@interface定义中也以这种方式声明它们很方便。

*) 给或取几个位置。


推荐阅读