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

Method with reordered type parameter bounds compiles with @Override annotation but does not actually override superclass method.

XMLWordPrintable

    • b139
    • generic
    • generic
    • Verified

      FULL PRODUCT VERSION :
      java version "1.8.0_74"
      Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
      Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      15.6.0 Darwin Kernel Version 15.6.0: Mon Aug 29 20:21:34 PDT 2016; root:xnu-3248.60.11~1/RELEASE_X86_64 x86_64


      A DESCRIPTION OF THE PROBLEM :
      1. A subclass implements a method with the same signature as a method in the super class, except that the bounds of a type parameter are reordered.
      2. The subclass method has an @Override annotation.
      3. javac compiles this code without any errors or warnings.
      4. When you call the method on a variable whose declared type is the superclass but run-time type is the subclass, the java runtime will dispatch to the superclass method, instead of the subclass method as implied by the @Override notation.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile my code below and run it. I did this with:

      javac ReorderedBounds.java ; java -cp . ReorderedBounds


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I was expecting to see the following output:

      OrderedChild
      ReorderedChild

      ACTUAL -
      Instead I saw this output:

      OrderedChild
      Parent


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.Serializable;

      /** An example where the compiler allows @Override but doesn't actually override the method. */
      public class ReorderedBounds {
        public static class Parent {
          public <T extends Appendable & Serializable> void printClassName(T t) {
            System.out.println("Parent");
          }
        }

        public static class OrderedChild extends Parent {
          @Override
          public <T extends Appendable & Serializable> void printClassName(T t) {
            System.out.println("OrderedChild");
          }
        }

        public static class ReorderedChild extends Parent {
          @Override
          public <T extends Serializable & Appendable> void printClassName(T t) {
            System.out.println("ReorderedChild");
          }
        }

        public static void main(String[] args) {
          Parent p = new OrderedChild();
          // We will get "OrderedChild" as expected.
          p.printClassName(new StringBuilder());

          p = new ReorderedChild();
          // We expect virtual dispatch to print "ReorderedChild", but instead we get "Parent".
          p.printClassName(new StringBuilder());
        }
      }

      ---------- END SOURCE ----------

            sadayapalam Srikanth Adayapalam (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: