code: private static int annHashCode(Annotation ann) {
          int hash = 0;
  
          Method[] methods = ann.getClass().getDeclaredMethods();
          for (Method m : methods) {
              if (m.getReturnType() == null || m.getReturnType() == void.class) {
                  continue;
              }
              if (m.getParameterTypes().length != 0) {
                  continue;
              }
  
              String name = m.getName();
              if (name.equals("hashCode") ||
                  name.equals("toString") ||
                  name.equals("annotationType"))
              {
                  continue;
              }
  
              Object value;
              try {
                  value = m.invoke(ann);
              } catch (InvocationTargetException e) {
                  continue;
              } catch (IllegalAccessException e) {
                  continue;
              }
  
              hash += (127 * name.hashCode()) ^ annValueHashCode(value);
          }
  
          return hash;
      }
docs: Returns an annotation hash code using a algorithm similar to the
  default. The difference is in the handling of class and enum values. The
  name is chosen for the hash code component instead of the instance
  because it is stable between invocations of the JVM.