code: public static <T extends Annotation> List<FieldWithAnnotation<T>> findFieldsWithAnnotation(Class<?> type,
        Class<T> annotationType) {
      ClassAnnotationCacheKey cacheKey = new ClassAnnotationCacheKey(type, annotationType);
  
      @SuppressWarnings("unchecked")
      List<FieldWithAnnotation<T>> cachedResults =
          (List<FieldWithAnnotation<T>>) FIELDS_WITH_ANNOTATION_CACHE.get(cacheKey);
  
      if (cachedResults != null) {
        return cachedResults;
      }
  
      List<FieldWithAnnotation<T>> fieldsWithAnnotation = new ArrayList<>();
  
      // Walk all superclasses looking for annotated fields until we hit Object
      while (!Object.class.equals(type) && type != null) {
        for (Field field : type.getDeclaredFields()) {
          T annotation = field.getAnnotation(annotationType);
          if (annotation != null) {
            fieldsWithAnnotation.add(new FieldWithAnnotation<>(field, annotation));
          }
  
        }
  
        type = type.getSuperclass();
      }
  
      fieldsWithAnnotation = unmodifiableList(fieldsWithAnnotation);
      FIELDS_WITH_ANNOTATION_CACHE.put(cacheKey, fieldsWithAnnotation);
      return fieldsWithAnnotation;
    }
docs: Finds fields on the given {@code type} and all of its superclasses annotated with annotations of type
  {@code annotationType}.
  
  @param <T>
  The annotation type.
  @param type
  The target type token.
  @param annotationType
  The annotation type token.
  @return A list of field/annotation pairs.