code: private static Optional<Integer> invariableHash(AnnotationValue annotationValue) {
      Object value = annotationValue.getValue();
      if (value instanceof String || Primitives.isWrapperType(value.getClass())) {
        return Optional.of(value.hashCode());
      } else if (value instanceof List<?>) {
        @SuppressWarnings("unchecked") // by specification
        List<? extends AnnotationValue> list = (List<? extends AnnotationValue>) value;
        return invariableHash(list);
      } else {
        return Optional.empty();
      }
    }
docs: Returns the hashCode of the given AnnotationValue, if that hashCode is guaranteed to be always
  the same. The hashCode of a String or primitive type never changes. The hashCode of a Class or
  an enum constant does potentially change in different runs of the same program. The hashCode of
  an array doesn't change if the hashCodes of its elements don't. Although we could have a
  similar rule for nested annotation values, we currently don't.