Uploaded image for project: 'Commons Lang'
  1. Commons Lang
  2. LANG-403

HashcodeBuilder is broken for Annotations

    XMLWordPrintableJSON

    Details

    • Type: Improvement
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 2.3
    • Fix Version/s: Patch Needed
    • Component/s: lang.builder.*
    • Labels:
      None

      Description

      HashCodeBuilder does not produce a correct hashCode that conforms to java language specs. Running the following code snippets, i get

      @Simple$CustomAnnotation(name=blah, type=class java.lang.String) hashCode= 895255138
      Simple$CustomAnnotationImpl@665753[_name=blah,_type=class java.lang.String] hashCode= 122852694
      hashCode should be 895255138

      The hashCode should computed according to http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/Annotation.html#hashCode() for annotations.

      public class Simple{
      
        @Retention(RetentionPolicy.RUNTIME)
        @Target({FIELD, METHOD, PARAMETER})
        private @interface CustomAnnotation{
      
          public String name();
          public Class<?> type();
        }
      
        private static class CustomAnnotationImpl implements CustomAnnotation{
          final String _name;
          final Class<?> _type;
      
          public CustomAnnotationImpl(String name, Class<?> type) {
            _name = name;
            _type = type;
          }
      
          public String name() {
            return _name;
          }
      
          public Class<?> type() {
            return _type;
          }
      
          public Class<? extends Annotation> annotationType() {
            return CustomAnnotation.class;
          }
      
          @Override
          public int hashCode() {
            return HashCodeBuilder.reflectionHashCode(this);
          }
      
          /**
           * This conform to specs defined at http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/Annotation.html#hashCode
           * @return good annotation hashCode
           */
          public int goodHashCode() {
            return (127 * "name".hashCode() ^ _name.hashCode()) + (127 *"type".hashCode() ^ _type.hashCode());
          }
          
          @Override
          public String toString() {
            return ToStringBuilder.reflectionToString(this);
          }
      
        }
      
        private static class Test{
          @CustomAnnotation(name="blah", type=String.class)
          String _blah;
          @Override
          public String toString() {
            return ToStringBuilder.reflectionToString(this);
          }
        }
      
        
        public static void main(String[] args) throws Exception{
          for(Field f : Test.class.getDeclaredFields()){
            for(Annotation a : f.getAnnotations()){
              System.out.println(a + " hashCode= " + a.hashCode());
              CustomAnnotationImpl c =  new Simple.CustomAnnotationImpl("blah", String.class);
              System.out.println(c + " hashCode= " + c.hashCode());
              System.out.println("hashCode should be "+ c.goodHashCode());
            }
          }
        }
      
      } 
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              jliang Jay Liang
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: