2

I have a Java annotation type like this:

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(METHOD)
public @interface Foo {

}

My intention is to avoid multiple instances of this annotation. In other words I want to disallow the next example code and throw an exception:

public class FooTest {
   @Foo
   public void method1(){...}
   @Foo
   public void method2(){...}
}

Any suggestion?

SDJ
  • 4,083
  • 1
  • 17
  • 35
D.Bertini
  • 29
  • 5
  • 2
    U can definetly use Refelction to see if more than one Method has the Exception also you could check at compile time for this https://medium.com/@jintin/annotation-processing-in-java-3621cb05343a – Alex Nov 15 '19 at 15:04
  • 1
    Annotation has no effect unless there is an annotation processor for it. So you have to implement a processor - that could be done with Reflection API as @Alex suggested – Vladimir Vagaytsev Nov 15 '19 at 15:15
  • Does this answer your question? [Prevent launching multiple instances of a java application](https://stackoverflow.com/questions/7036108/prevent-launching-multiple-instances-of-a-java-application) – Remzi Cavdar Oct 31 '22 at 11:24

1 Answers1

1

The best technique to fulfill your intention (avoid multiple instances of this annotation) would be a static check, simply because it can be done and would detect the problem earlier. This is supported through Java's annotation processing feature.

However, the question also shows a desire to do this at run-time given that it includes @Retention(RUNTIME) and mentions exceptions. This can be done easily with reflection if the list of classes to check is known in advance. Here's a simple piece of code to check one class, since the question mentions checking a single class.

public static void checkClass(Class<?> clazz) {
    boolean used = false;
    for( Method method : clazz.getDeclaredMethods() ) {
        if( method.getAnnotation(Foo.class) != null ) {
            if( used ) { 
                throw new IllegalFooUseException(); 
            }
            else { used = true; }
        }
    }
}

Checking across a project would be more work, as it would require collecting all the classes in the project, which isn't so simple.

SDJ
  • 4,083
  • 1
  • 17
  • 35