【问题标题】:Understanding the use of 'Annotations'了解“注释”的使用
【发布时间】:2018-03-14 12:20:02
【问题描述】:

我正在尝试更好地理解“注释”的使用。 我明白了:

为了更好地理解这一点,我创建了一个虚拟问题如下:

注解TestAnnotation1TestAnnotation2TestAnnotation3(问题后面有定义)。我想执行MethodsExecutorClass类的方法如下:

  • TestClass.java编译然后执行CommonMethod()RetentionPolicySOURCEMethod()
  • TestClass.class 加载然后执行CommonMethod()RetentionPolicyCLASSMethod()
  • 每当TestClass.javatestMethod() 方法执行然后执行CommonMethod()RetentionPolicyRUNTIMEMethod()

通过这个例子,我想了解以下内容

  • 我能否指示 Java 编译器 (javac) 或 Java 运行时环境 (jvm) 在我的类中执行一个方法(例如 CommonMethod()andRetentionPolicySOURCEMethod()methods ofMethodsExecutorClass`)。
  • 我能否将监控(即搜索使用我的注解的方法/类等)委托给任何其他实体(在Java SE 中可用)。
  • 我想做一些类似@Override@deprecated 注释的事情。我们不做额外的事情。尽管on Oracle javadoc site, here 明确提到 Java 平台一直有各种特殊的注解机制。@deprecated 就是其中之一。但我想知道我是否可以做这样的事情。

定义应如下所示:

MyAnnotations.java

@Retention(RetentionPolicy.SOURCE)
public @interface TestAnnotation1 
{
  String className();
}

@Retention(RetentionPolicy.CLASS)
public @interface TestAnnotation2 
{
  String className();
}

@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation3 
{
  String className();
  String methodName();
}

MethodsExecutorClass.java

class MethodsExecutorClass
{
    public static void CommonMethod()
    {
        System.out.println("In method: CommonMethod()");
    }

    public void RetentionPolicySOURCEMethod()
    {
        System.out.println("In method: RetentionPolicySOURCEMethod()");
        //Also print annotation arguments e.g. Class name etc
    }

    public void RetentionPolicyCLASSMethod()
    {
        System.out.println("In method: RetentionPolicyCLASSMethod()");
        //Also print annotation arguments e.g. Class name etc
    }

    public void RetentionPolicyRUNTIMEMethod()
    {
        System.out.println("In method: RetentionPolicyRUNTIMEMethod()");
        //Also print annotation arguments e.g. Class name etc
    }
}

TestClass.java

@TestAnnotation1(TestClass.class)
@TestAnnotation2(TestClass.class)
class TestClass
{
    @TestAnnotation2(TestClass.class, "testMethod()")
    public void testMethod()
    {
        System.out.println("In method: testMethod()");
    }
} 

您能帮我实现这一目标吗? (请不要猜测或假设,但假设也会有帮助)。
我不确定这是否可以实现,但期待。

【问题讨论】:

  • 您是否正在寻找如何通过 Java 中的反射机制使用注解?
  • @statut 不,我在 Internet 上有几个关于此的示例。我想做一些类似的事情,我将提供我的注释(TestAnnotation1TestAnnotation2 等)和 _classes 具有在不同场景上执行的方法_(例如MethodsExecutorClass)。现在,当任何开发人员正在编译/运行他的代码时(他可能会或可能不会使用我的注释),那么应该调用相应的方法(例如CommonMethod())。开发者可能需要做一些配置(例如我们设置CLASS_PATH),否则他不应该被打扰。
  • 我可以将整个源文件传递给我的另一个类(例如HandleCompileTimeAnnotations)来处理SOURCE 保留策略,但是 我不想做这样的事情
  • Java中有“自定义注解”的概念。您可以构建自己的,并根据需要实施。
  • @UmeshKumarSharma 我已经定义了 Custom Annotation 例如TestAnnotation1 TestAnnotation2 等。但我不知道如何实现这个?。因为我事先不知道哪些其他类正在使用我的Custom Annotation。此外,可能是其他用户将来定义了他的类并使用自定义注释

标签: java annotations jvm


【解决方案1】:

具有保留策略RetentionPolicy.SOURCE 的注解仅在代码编译期间可用,因此您的编译器应支持您的注解使用它,否则无法处理该注解。通常,此类注解用于在编译时检测可能出现的问题,例如注解@Override。这就是为什么你的第一个问题不能以通常的方式实现的原因。

具有保留策略RetentionPolicy.CLASS 的注释仅在.class 文件中可用,并且可以通过 JVM 使用。请参阅this answer 如何使用它。第二个您的问题也无法通过标准方式实现。

常用的注释带有保留策略RetentionPolicy.RUNTIME,可通过Java 中的reflection mechanism 获得。但是要解决您的第三个问题,您必须使用一些方法调用拦截器,例如,通过Aspect Oriented Programming。之后你可以通过method.getDeclaredAnnotations()获取方法的注解。

我可以指示 Java 编译器 (javac) 或 Java 运行时环境 (jvm) 在我的类中执行一个方法(例如 CommonMethod() 和 RetentionPolicySOURCEMethod() 方法 ofMethodsExecutorClass`)。

不,你不能。

我可以委托监控吗(即搜索方法/类 正在使用我的注释等)到任何其他实体(即 在 Java SE 中可用)。

您可以通过 AOP 来实现,例如,使用库 AspectJ

【讨论】:

  • 我理解 RetentionPolicy 这就是为什么我希望只在编译时而不是稍后调用RetentionPolicySOURCEMethod()。我不想做类似@Override@deprecated 注释的事情。我们不做额外的事情。尽管on Oracle javadoc site, here 明确提到 Java 平台一直有各种ad hoc 注解机制。@deprecated 就是其中之一。但我想知道我是否可以做这样的事情。
  • 如果你实现自己的编译器,你可以这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-24
  • 2022-08-09
  • 2010-12-29
  • 1970-01-01
  • 2021-11-08
  • 2011-03-24
  • 2021-12-24
相关资源
最近更新 更多