5

This question is a follow up to a question I found before
java: get all variable names in a class

What I want is to get variables from a class, but instead of getting them all, I want only the variables that have the annotation @isSearchable .

So basically I have 2 questions :

  • How do I create an annotation ?

  • How to filter my fields by only this annotation ?

And one more thing , if it is something I'm using frequently is it advisable (I'm guessing reflections should be slow).

Thank you

Community
  • 1
  • 1
Dany Y
  • 6,833
  • 6
  • 46
  • 83
  • @T.J.Crowder I wasn't familiar with Annotations or if this is a use case for them. Thank you all for your answers, this was really helpful – Dany Y Dec 27 '12 at 10:47

4 Answers4

3
/** Annotation declaration */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface isSearchable{
    //...   
}

@isSearchable
public String anyField = "any value";

checking like:

//use MyClass.class.getDeclaredFields() if you want the fields only for this class.
//.getFields() returns the fields for all the class hierarchy
for(Field field : MyClass.class.getFields()){
    isSearchable s = field.getAnnotation(isSearchable.class);
    if (s != null) {
        //field has the annotation isSearchable
    } else {
        //field has not the annotation
    }
}
Abdullah Khan
  • 12,010
  • 6
  • 65
  • 78
vishal_aim
  • 7,636
  • 1
  • 20
  • 23
  • Still one question, is it advisable to use it just to economize some code writing everytime ? – Dany Y Dec 27 '12 at 10:40
  • it depends, generally we should avoid reflection as it involves the overhead, but if much is gained in terms of maintanability/readability/testability, I think we can use it. and should rely on profilers to know the area for optimization if needed – vishal_aim Dec 27 '12 at 10:43
2

How to filter my fields by only this annotation ?

You can get by this simple snippet

Field field = ... //obtain field object
Annotation[] annotations = field.getDeclaredAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof IsSearchable){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}

In the above snippet you are basically filtering only IsSearchable annotations.

Regarding your one more thing query

Yes reflection will be slow as discussed here, if its possible to avoid, would advise you to avoid.

Community
  • 1
  • 1
Jayamohan
  • 12,734
  • 2
  • 27
  • 41
2

Here is an example

class Test {
    @IsSearchable
    String str1;
    String str2;

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @interface IsSearchable {
    }

    public static void main(String[] args) throws Exception {
        for (Field f : Test.class.getDeclaredFields()) {
            if (f.getAnnotation(IsSearchable.class) != null) {
                System.out.println(f);
            }
        }
    }
}

prints

java.lang.String Test.str1
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
1

Field.getDeclaredAnnotations() gives you the annotations for each field.

To answer your supplementary question, I would normally expect reflection to be slow. Having said that, I perhaps wouldn't worry about optimising until this becomes a problem for you.

Hint: Make sure you're checking the up-to-date Javadoc. Google tends to give me Java 1.4 Javadocs, and annotations didn't exist prior to Java 5.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Brian Agnew
  • 268,207
  • 37
  • 334
  • 440