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

6.5: Unwieldy selection for an interface method ref by invokespecial



    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 11
    • Fix Version/s: 12
    • Component/s: specification
    • Labels:
    • Subcomponent:


      When a Java class has multiple superinterfaces with conflicting default methods, the class can disambiguate by declaring a method that (i) overrides all the defaults, and (ii) picks a winner via the `super` feature:

      interface I { default void m() {...} }
      interface J { default void m() {...} }
      class X implements I,J { public void m() { I.super.m(); } }

      This results in X.class containing `invokespecial I.m`, that is, an invokespecial whose symbolic reference names an interface. At run time, `I.m` is resolved, and then there is no need to search X's superclass hierarchy for m; the search starts at I, and is immediately successful (though if I had superinterfaces, they would be searched next).

      It has been pointed out (http://mail.openjdk.java.net/pipermail/jls-jvms-spec-comments/2018-September/000045.html) that the search policy is misworded when the symbolic reference names an interface. Specifically, one of the tests for where to start searching -- "If the symbolic reference names a class (not an interface), then that class is a superclass of the current class." -- will succeed vacuously if the symbolic reference names an interface. The outcome is that "C" will be determined to be X, and X's superclass hierarchy will be searched, and in fact _only_ X's superclass hierarchy, not its superinterface hierarchy -- implying, wrongly, that m in I should not be found.

      (This relies on reading steps 2, 3, and 4 of the lookup procedure as mutually exclusive. If, however, the intent is to execute step 1, then potentially step 2, and then potentially step 4 (let's set aside the uncommon situation in step 3), then the procedure should clarify the flow at the end of step 2. But this intent is unlikely because step 4 would cast a wide net over _all_ of X's superinterfaces, not just X's direct superinterfaces as is proper for the `super` feature.)

      To prevent the test from vacuously catching X's symbolic reference to I, the test should say: "The symbolic reference names a class (not an interface), and that class is a superclass of the current class."


          Issue Links



              abuckley Alex Buckley
              abuckley Alex Buckley
              0 Vote for this issue
              2 Start watching this issue