views:

110

answers:

1
+1  Q: 

Smart annotation

Hi

I have created many annotation in my life and now came to strange case that i need this annotation to do and dont think it is supported by Java at all. Please someone tell me that i am right or wrong.

Here is my annotation :

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DetailsField {
    public String name();
}

And now the question! I would like that the default value of the name() function would be the name of the field it self where I have posted the annotation.

Dont know exactly how the classloader processes the annotations, i am pretty sure that this is not implemented in a standard classloader , but could be maybe achieved by bytecode instrumentation in the time of classloading by a custom classloader ? (I am pretty sure if this is the only solution i would find a way around , just curious )

Any ideas? Or do i wish too much ?

+3  A: 

I think that it is possible to instrument the bytecode (at class loading) to get this working, but this seems like a highly complicated, and possibly non-portable, solution.

The best solution to your problem is to create a class that decorates (a-la the Decorator design pattern) an instance of your annotation with the name calculation logic.

[Edit: Added the name() definition at the interface]

package p1;

import java.lang.annotation.*;
import java.lang.reflect.*;

public class A {
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.FIELD)
  public @interface DetailsField  {
     public int n1();   
     public String name() default "";     
  }

  public static class Nameable implements DetailsField {
     private final DetailsField df;
     private final Field f;

     public Nameable(Field f) {
        this.f = f;
        this.df = f.getAnnotation(DetailsField.class);
     }

     @Override
     public Class<? extends Annotation> annotationType() {
        return df.annotationType();
     }

     @Override
     public String toString() {
        return df.toString();
     }

     @Override
     public int n1() {
        return df.n1();
     }

     public String name() {
        return f.getName();
     }   
  }

  public class B {
     @DetailsField(n1=3)
     public int someField;
  }

  public static void main(String[] args) throws Exception {
     Field f = B.class.getField("someField");

     Nameable n = new Nameable(f);
     System.out.println(n.name()); // output: "someField"
     System.out.println(n.n1());   // output: "3"
  }
}
Itay
Absolutely awesome... !!!Thanks a lot!
Roman