A. Vasyukhin
A. Vasyukhin

Reputation: 99

Cannot resolve annotation parameter

I study annotations and in one of learning tasks I must inject some implementations of cache annotated as @Cache to fields annotated as @InjectCache.

I wrote this code but I get cannot resolve symbol name() error on expression cache.getAnnotation(Cache.class).name() but field.getAnnotation(InjectCache.class).name() couple of strings earlier resolves without errors.

@Cache and @InjectCache both has parameter name(), and they only difference is a @TARGET annotation.

  package annotations;

  import annotations_test.MapCache;
  import annotations_test.SortedMapCache;
  import java.lang.reflect.Field;
  import java.lang.reflect.Type;
  import java.util.ArrayList;
  import java.util.List;

  public class Injector {
        public static void inject(Object instance){
            List<Field> fields = new ArrayList<Field>();
            List<Class> caches;
            caches = addAllCaches();
            fields = getAnnotatedFields(fields, instance.getClass());
            try {
            for (Field field : fields) {
                field.setAccessible(true);
                String name = field.getAnnotation(InjectCache.class).name();
                Boolean implementation_not_found = true;
                for (Class cache: caches){

                        if (name.equals(cache.getAnnotation(Cache.class).name())){
                            implementation_not_found = false;
                            field.set(instance, cache.newInstance());

                        }
                }
                if (implementation_not_found){
                    throw new TypeNotPresentException(Cache.class.getTypeName(),null);
                }

            }
            }catch (TypeNotPresentException e){
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

This is what @Cache looks like:

package annotations;

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



@Target(value= ElementType.TYPE)
@Retention(value= RetentionPolicy.RUNTIME)
public @interface Cache {
    String name();
}

And @InjectCache:

package annotations;

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



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

Upvotes: 2

Views: 3090

Answers (1)

kapex
kapex

Reputation: 29959

You get this error because Class cache in the for loop is a raw type.

You need to change it to have a generic type (even if it is just the wildcard <?>):

for (Class<?> cache: caches) {
  // ...
}

The reason for this is, that you can't use any generic methods with raw types. Without the wildcard, the return type of getAnnotation(Cache.class) is Annotation and not the Cache annotation type.

Adding the wildcard is your best option because it makes the getAnnotation method type-safe. You can also cast it to the right type though:

((Cache)cache.getAnnotation(Cache.class)).name()

Upvotes: 1

Related Questions