代码之家  ›  专栏  ›  技术社区  ›  sinuhepop

为什么不能在Java中扩展注释?

  •  216
  • sinuhepop  · 技术社区  · 16 年前

    我不明白为什么Java注释中没有继承,就像Java类一样。我认为这会非常有用。

    ValidatorAnnotation . 否则,我如何才能做到这一点?

    8 回复  |  直到 8 年前
        1
  •  174
  •   Walery Strauch Lia    6 年前

    关于为什么它不是这样设计的,你可以在 JSR 175 设计常见问题,其中说明:

    难以编写特定的工具。

    任意类型的已知注释 外部程序。短线发生器, 这些程序将读取注释 类,而不将它们加载到 虚拟机,但将加载 注释接口。

    JSR 308 ,您甚至可以找到一个具有此功能的替代编译器 Mathias Ricken .

        2
  •  72
  •   alphazero    16 年前

    所有这些都增加了什么用例的复杂性?

    您想知道给定注释是否属于某个类别?

    试试这个:

    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Category {
        String category();
    }
    
    @Category(category="validator")
    public @interface MyFooBarValidator {
    
    }
    

    正如您所看到的,您可以使用提供的工具轻松地对注释进行分组和分类,而不会带来不必要的麻烦。

    KISS 是不在Java语言中引入元类型系统的原因。

    [附后编辑]

    我使用这个字符串只是为了演示和查看一个开放式元注释。对于您自己的给定项目,显然可以使用类别类型的枚举,并为给定注释指定多个类别(“多重继承”)。请注意,这些值完全是假的,仅用于演示目的:

    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Category {
        AnnotationCategory[] category();
    }
    public enum AnnotationCategory {
        GENERAL,
        SEMANTICS,
        VALIDATION,
        ETC
    }
    
    @Category(category={AnnotationCategory.GENERAL, AnnotationCategory.SEMANTICS})
    public @interface FooBarAnnotation {
    
    }
    

        3
  •  12
  •   Yishai    16 年前

    在某种意义上,你已经有了注释——元注释。如果使用元信息对注释进行注释,这在许多方面相当于扩展一个附加接口。注释是接口,所以多态性并没有真正发挥作用,因为它们本质上是静态的,所以不可能有运行时动态调度。

    我所能看到的唯一一个继承有帮助的用例是,如果您希望能够通过超级类型获得注释,但这会增加一大堆复杂性,因为给定的方法或类型可能有两个这样的注释,这意味着必须返回一个数组,而不仅仅是一个对象。

    因此,我认为最终的答案是,用例是深奥的,并且使更多的标准用例变得复杂,因此不值得这么做。

        4
  •  5
  •   Konstantin Komissarchik    12 年前

    Java注释支持的设计者对Java社区进行了许多“简化”。

    1. 无注释子类型会使许多复杂注释变得不必要的丑陋。不能简单地在注释中包含一个属性,该属性可以包含以下三种内容之一。一个需要有三个单独的属性,这会混淆开发人员,需要运行时验证以确保只使用三个属性中的一个。

    2. 每个站点只有一个给定类型的注释。这导致了完全不必要的集合注释模式@验证和@Validations、@Image和@Images等。

        5
  •  3
  •   Necreaux    9 年前

    我可能晚了三年才回答这个问题,但我发现这很有趣,因为我发现自己也在这个问题上。这是我的看法。可以将批注作为枚举查看。它们提供的信息是单向的——要么使用,要么丢失。

    我曾经遇到过这样一种情况,我想在web应用程序中模拟GET、POST、PUT和DELETE。我非常希望有一个名为“HTTP_方法”的“超级”注释。后来我才明白这没关系。嗯,我不得不在HTML表单中使用一个隐藏字段来标识DELETE和PUT(因为POST和GET无论如何都是可用的)。

    因此,在您的情况下,不要急于扩展注释。将它们视为“标记”。它们“代表”某些信息,而不一定“操纵”某些信息。

        6
  •  2
  •   Janusz Daniel Rindt    16 年前

    我能想到的一件事是有多个注释的可能性。因此,您可以在同一位置添加验证器和更具体的注释。但我可能弄错了:)

        7
  •  2
  •   denis.zhdanov    16 年前

    关于你的例子 “验证器” “元注释”

        8
  •  1
  •   ante.sabo    16 年前

    我也有同样的问题。不,你不能。我确实“训练”自己在注释中编写属性以遵守一些标准,所以在外部,当您得到注释时,您可以通过其属性“嗅探”它是什么类型的od注释。