Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8039163

Bad TypeVariable.equals() method implementation in TypeVariableImpl

XMLWordPrintable

      FULL PRODUCT VERSION :
      1.8.0

      ADDITIONAL OS VERSION INFORMATION :
      Linux ivostmaina 3.13.6-gentoo #1 SMP Thu Mar 20 02:22:16 CET 2014 x86_64 AMD FX(tm)-8350 Eight-Core Processor AuthenticAMD GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      From the description of the interface TypeVariable:

      Multiple objects may be instantiated at run-time to represent a given type variable. Even though a type variable is created only once, this does not imply any requirement to cache instances representing the type variable. However, all instances representing a type variable must be equal() to each other. As a consequence, users of type variables must not rely on the identity of instances of classes implementing this interface.

      But in the actual implementation TypeVariableImpl.java (http://hg.openjdk.java.net/jdk8/tl/jdk/file/183a8c520b4a/src/share/classes/sun/reflect/generics/reflectiveObjects/TypeVariableImpl.java) I see that equals() behaves wrong.

          @Override
          public boolean equals(Object o) {
              if (o instanceof TypeVariable &&
                      o.getClass() == TypeVariableImpl.class) {
                  TypeVariable<?> that = (TypeVariable<?>) o;

                  GenericDeclaration thatDecl = that.getGenericDeclaration();
                  String thatName = that.getName();

                  return Objects.equals(genericDeclaration, thatDecl) &&
                      Objects.equals(name, thatName);

              } else
                  return false;
          }

      The Test "o.getClass() == TypeVariableImpl.class" violates the requirement from the description "As a consequence, users of type variables must not rely on the identity of instances of classes implementing this interface."

      REGRESSION. Last worked in version 8


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      @Test
      @SuppressWarnings("rawtypes")
      public void java8_typevariable_equals_and_hashcode() {

      class MyClass<T> {

      }

      final TypeVariable<Class<MyClass>> v = MyClass.class.getTypeParameters()[0];

      final TypeVariable<Class<MyClass>> vcp = new TypeVariable<Class<MyClass>>() {

      @Override
      public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
      return v.getAnnotation(annotationClass);
      }

      @Override
      public Annotation[] getAnnotations() {
      return v.getAnnotations();
      }

      @Override
      public Annotation[] getDeclaredAnnotations() {
      return v.getDeclaredAnnotations();
      }

      @Override
      public Type[] getBounds() {
      return v.getBounds();
      }

      @Override
      public Class<MyClass> getGenericDeclaration() {
      return v.getGenericDeclaration();
      }

      @Override
      public String getName() {
      return v.getName();
      }

      @Override
      public AnnotatedType[] getAnnotatedBounds() {
      return v.getAnnotatedBounds();
      }

      @Override
      public int hashCode() {
      return Objects.hashCode(getName()) ^ Objects.hashCode(getGenericDeclaration());
      }

      @Override
      public boolean equals(Object obj) {

      if (obj == this)
      return true;

      if (!(obj instanceof TypeVariable))
      return false;
      TypeVariable<?> other = (TypeVariable<?>) obj;

      return ObjectUtils.equals(getGenericDeclaration(), other.getGenericDeclaration())
      && ObjectUtils.equals(getName(), other.getName());
      }

      };

      assertEquals(v.hashCode(), vcp.hashCode());
      assertEquals(vcp, v);
      assertEquals(v, vcp); // FAILS HERE
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      No nice workaround.

            liach Chen Liang
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: