test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/PrivateMethodsTest.java
changeset 50735 2f2af62dfac7
parent 50243 4fac3c99487d
equal deleted inserted replaced
50734:0828a0f6676b 50735:2f2af62dfac7
    46     // invokevirtual & invokeinterface from same/subintf
    46     // invokevirtual & invokeinterface from same/subintf
    47     // Spec change July 2013 to not allow invokevirtual or invokeinterface
    47     // Spec change July 2013 to not allow invokevirtual or invokeinterface
    48     // to even see an interface private method
    48     // to even see an interface private method
    49     // Throw ICCE if method resolution returns interface private method
    49     // Throw ICCE if method resolution returns interface private method
    50 
    50 
       
    51     // Spec change JDK 11 - invokeinterface can be used for private interface
       
    52     // methods and is now the preferred invocation bytecode - so no ICCE.
       
    53     // Private methods are skipped during selection unless the resolved method
       
    54     // is private.
       
    55     // This change is not dependent on the classfile version.
       
    56 
       
    57     // Note on reflection testing:
       
    58     //   Reflection is only used for the initial callsite, which is not always
       
    59     //   the method of interest. For example where a default method m() calls
       
    60     //   the private interface method privateM(). It is the latter call we are
       
    61     //   really testing, but it is the call of the default method that occurs
       
    62     //   via reflection.
       
    63     //   In private cases reflection triggers a NoSuchMethodException instead of the
       
    64     //   expected IllegalAccessError. This indicates it is getDeclaredMethod() that is
       
    65     //   failing rather than the actual invoke(). Which in turn suggests the wrong class
       
    66     //   is being used, or that getMethod() is being used instead of getDeclaredMethod().
       
    67 
    51     /*
    68     /*
    52      * testPrivateInvokeVirtual
    69      * testPrivateInvokeVirtual
    53      *
    70      *
    54      * interface I {
    71      * interface I {
    55      *   default private int privateM() { return 1; }
    72      *           private int privateM() { return 1; }
    56      *   default public  int m()        { return (I)this.privateM(); } // invokevirtual
    73      *   default public  int m()        { return (I)this.privateM(); } // invokevirtual
    57      * }
    74      * }
    58      * class C implements I {}
    75      * class C implements I {}
    59      *
    76      *
    60      * TEST: I o = new C(); o.m()I throws VerifyError
    77      * TEST: I o = new C(); o.m()I throws VerifyError
    83 
   100 
    84     /*
   101     /*
    85      * testPrivateInvokeIntf
   102      * testPrivateInvokeIntf
    86      *
   103      *
    87      * interface I {
   104      * interface I {
    88      *   default private int privateM() { return 1; }
   105      *           private int privateM() { return 1; }
    89      *   default public  int m()        { return (I)this.privateM(); } // invokeinterface
   106      *   default public  int m()        { return (I)this.privateM(); } // invokeinterface
       
   107      * }
       
   108      * class C implements I {}
       
   109      *
       
   110      * TEST: I o = new C(); o.m()I returns 1
       
   111      * TEST: C o = new C(); o.m()I returns 1
       
   112      */
       
   113     public void testPrivateInvokeIntf() {
       
   114         TestBuilder b = factory.getBuilder();
       
   115 
       
   116         Interface I = b.intf("I")
       
   117                 .defaultMethod("privateM", "()I")
       
   118                     .private_().returns(1).build()
       
   119                 .defaultMethod("m", "()I")
       
   120                     .invoke(INTERFACE, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build()
       
   121             .build();
       
   122 
       
   123         ConcreteClass C = b.clazz("C").implement(I).build();
       
   124 
       
   125         b.test().callSite(I, C, "m", "()I").returns(1).done()
       
   126          .test().callSite(C, C, "m", "()I").returns(1).done()
       
   127 
       
   128         .run();
       
   129     }
       
   130 
       
   131     /*
       
   132      * testPrivateInvokeStatic
       
   133      *
       
   134      * interface I {
       
   135      *           private int privateM() { return 1; }
       
   136      *   default public  int m()        { return I.privateM(); } // invokestatic
    90      * }
   137      * }
    91      * class C implements I {}
   138      * class C implements I {}
    92      *
   139      *
    93      * TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError
   140      * TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError
    94      * TEST: C o = new C(); o.m()I throws IncompatibleClassChangeError
   141      * TEST: C o = new C(); o.m()I throws IncompatibleClassChangeError
    95      */
   142      */
    96     public void testPrivateInvokeIntf() {
   143     public void testPrivateInvokeStatic() {
    97         TestBuilder b = factory.getBuilder();
   144         TestBuilder b = factory.getBuilder();
    98 
   145 
    99         Interface I = b.intf("I")
   146         Interface I = b.intf("I")
   100                 .defaultMethod("privateM", "()I")
   147                 .defaultMethod("privateM", "()I")
   101                     .private_().returns(1).build()
   148                     .private_().returns(1).build()
   102                 .defaultMethod("m", "()I")
   149                 .defaultMethod("m", "()I")
   103                     .invoke(INTERFACE, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build()
   150                     .invoke(STATIC, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build()
   104             .build();
   151             .build();
   105 
   152 
   106         ConcreteClass C = b.clazz("C").implement(I).build();
   153         ConcreteClass C = b.clazz("C").implement(I).build();
   107 
   154 
   108         b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()
   155         b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()
   109          .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()
   156          .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()
   110 
   157 
   111         .run();
   158         .run();
   112     }
   159     }
   113 
   160 
   114     /*
       
   115      * testPrivateInvokeStatic
       
   116      *
       
   117      * interface I {
       
   118      *   default private int privateM() { return 1; }
       
   119      *   default public  int m()        { return I.privateM(); } // invokestatic
       
   120      * }
       
   121      * class C implements I {}
       
   122      *
       
   123      * TEST: I o = new C(); o.m()I throws LinkageError
       
   124      * TEST: C o = new C(); o.m()I throws LinkageError
       
   125      */
       
   126     public void testPrivateInvokeStatic() {
       
   127         TestBuilder b = factory.getBuilder();
       
   128 
       
   129         Interface I = b.intf("I")
       
   130                 .defaultMethod("privateM", "()I")
       
   131                     .private_().returns(1).build()
       
   132                 .defaultMethod("m", "()I")
       
   133                     .invoke(STATIC, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build()
       
   134             .build();
       
   135 
       
   136         ConcreteClass C = b.clazz("C").implement(I).build();
       
   137 
       
   138         b.test().callSite(I, C, "m", "()I").throws_(LinkageError.class).done()
       
   139          .test().callSite(C, C, "m", "()I").throws_(LinkageError.class).done()
       
   140 
       
   141         .run();
       
   142     }
       
   143 
       
   144     // call from another default method in the same interface
   161     // call from another default method in the same interface
   145     /*
   162     /*
   146      * testPrivateCallSameClass
   163      * testPrivateCallSameClass
   147      *
   164      *
   148      * interface I {
   165      * interface I {
   149      *   default private privateM()I { return 1; }
   166      *           private privateM()I { return 1; }
   150      *   default public int m() { return I.super.privateM(); }
   167      *   default public int m() { return I.super.privateM(); } // invokespecial
   151      * }
   168      * }
   152      * class C implements I {}
   169      * class C implements I {}
   153      *
   170      *
   154      * TEST: { I o = new C(); o.m()I  == 1; }
   171      * TEST: { I o = new C(); o.m()I  == 1; }
   155      * TEST: { C o = new C(); o.m()I  == 1; }
   172      * TEST: { C o = new C(); o.m()I  == 1; }
   176      * testPrivateCallSubIntf
   193      * testPrivateCallSubIntf
   177      *
   194      *
   178      * Attempt to call from subinterface fails
   195      * Attempt to call from subinterface fails
   179 
   196 
   180      * interface I {
   197      * interface I {
   181      *   default private privateM()I { return 1; }
   198      *   private privateM()I { return 1; }
   182      * }
   199      * }
   183      * J, K, L use invokespecial
   200      * J, K, L use invokespecial
   184      * interface J extends I {
   201      * interface J extends I {
   185      *   default public int m() { return I.super.privateM(); }
   202      *   default public int m() { return I.super.privateM(); }
   186      * }
   203      * }
   246 
   263 
   247     /*
   264     /*
   248      * Attempt to call from subclass fails
   265      * Attempt to call from subclass fails
   249      *
   266      *
   250      * interface I {
   267      * interface I {
   251      *   default private privateM()I { return 1; }
   268      *   private privateM()I { return 1; }
   252      * }
   269      * }
   253      * class C implements I {
   270      * class C implements I {
   254      *   public int m() { return I.super.privateM(); }
   271      *   public int m() { return I.super.privateM(); }
   255      * }
   272      * }
   256      * class D extends C {
   273      * class D extends C {
   258      * }
   275      * }
   259      * class E extends C {
   276      * class E extends C {
   260      *   public int m() { return C.super.privateM(); }
   277      *   public int m() { return C.super.privateM(); }
   261      * }
   278      * }
   262      *
   279      *
   263      * TEST: { C o = new C(); o.m()I throws LinkageError }
   280      * TEST: { C o = new C(); o.m()I throws IllegalAccessError (or VerifyError) }
   264      * TEST: { D o = new D(); o.m()I throws LinkageError }
   281      * TEST: { D o = new D(); o.m()I throws VerifyError }
   265      * TEST: { E o = new E(); o.m()I throws NoSuchMethodError; }
   282      * TEST: { E o = new E(); o.m()I throws NoSuchMethodError (or VerifyError); }
   266      */
   283      */
   267     @NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading
   284     @NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading
   268     public void testPrivateCallImplClass() {
   285     public void testPrivateCallImplClass() {
   269         TestBuilder b = factory.getBuilder();
   286         TestBuilder b = factory.getBuilder();
   270 
   287 
   287                 .concreteMethod("m", "()I")
   304                 .concreteMethod("m", "()I")
   288                     .invokeSpecial(C, "privateM", "()I").build()
   305                     .invokeSpecial(C, "privateM", "()I").build()
   289             .build();
   306             .build();
   290 
   307 
   291         Class eeExpectedClass;
   308         Class eeExpectedClass;
       
   309         Class ccExpectedClass;
   292         if (factory.getVer() >= 52) {
   310         if (factory.getVer() >= 52) {
   293             eeExpectedClass = NoSuchMethodError.class;
   311             eeExpectedClass = NoSuchMethodError.class;
       
   312             ccExpectedClass = IllegalAccessError.class;
   294         } else {
   313         } else {
   295             // The test gets a VerifyError in this case due to an
   314             // The test gets a VerifyError in this case due to an
   296             // invokespecial IMR bytecode.  This was not allowed
   315             // invokespecial IMR bytecode.  This was not allowed
   297             // until class file version 52.  (See 8030249.)
   316             // until class file version 52.  (See 8030249.)
   298             eeExpectedClass = VerifyError.class;
   317             eeExpectedClass = VerifyError.class;
       
   318             ccExpectedClass = VerifyError.class;
   299         }
   319         }
   300         b.test().callSite(C, C, "m", "()I").throws_(LinkageError.class).done()
   320         b.test().callSite(C, C, "m", "()I").throws_(ccExpectedClass).done()
   301          .test().callSite(D, D, "m", "()I").throws_(LinkageError.class).done()
   321          .test().callSite(D, D, "m", "()I").throws_(VerifyError.class).done()
   302          .test().callSite(E, E, "m", "()I").throws_(eeExpectedClass).done()
   322          .test().callSite(E, E, "m", "()I").throws_(eeExpectedClass).done()
   303 
   323 
   304         .run();
   324         .run();
   305     }
   325     }
   306 
   326 
   307     // doesn't participate in default method analysis
   327     // doesn't participate in default method analysis
   308     //   method overriding
   328     //   method overriding
   309 
   329 
   310     /*
   330     /*
   311      * testPrivateDefault
   331      * testPrivate
   312      *
   332      *
   313      * interface I {
   333      * interface I {
   314      *   default private int m() { return 1; }
   334      *   private int m() { return 1; }
   315      * }
   335      * }
   316      * class C implements I {}
   336      * class C implements I {}
   317      *
   337      *
   318      * TEST: { I o = new C(); o.m()I throws IllegalAccessError; }
   338      * TEST: { I o = new C(); o.m()I throws IllegalAccessError; }
   319      *                 -mode reflect throws NoSuchMethodException
   339      *                 -mode reflect throws NoSuchMethodException
   320      * TEST: { C o = new C(); o.m()I throws java/lang/NoSuchMethodError; }
   340      * TEST: { C o = new C(); o.m()I throws NoSuchMethodError; }
   321      */
   341      */
   322     public void testPrivateDefault() {
   342     public void testPrivate() {
   323         TestBuilder b = factory.getBuilder();
   343         TestBuilder b = factory.getBuilder();
   324 
   344 
   325         Interface I = b.intf("I")
   345         Interface I = b.intf("I")
   326                 .defaultMethod("m", "()I")
   346                 .defaultMethod("m", "()I")
   327                     .private_().returns(1).build()
   347                     .private_().returns(1).build()
   341 
   361 
   342         .run();
   362         .run();
   343     }
   363     }
   344 
   364 
   345     /*
   365     /*
   346      * testPrivateDefaultVsConcrete
   366      * testPrivateVsConcrete
   347      *
   367      *
   348      * interface I {
   368      * interface I {
   349      *   default private int m() { return 1; }
   369      *   private int m() { return 1; }
   350      * }
   370      * }
   351      * class C implements I {
   371      * class C implements I {
   352      *   public int m() { return 2; }
   372      *   public int m() { return 2; }
   353      * }
   373      * }
   354      *
   374      *
   355      * TEST: { I o = new C(); o.m()I  == IllegalAccessError; }
   375      * TEST: { I o = new C(); o.m()I  == IllegalAccessError; }
   356      *                 -mode reflect throws NoSuchMethodException
   376      *                 -mode reflect throws NoSuchMethodException
   357      * TEST: { C o = new C(); o.m()I  == 2; }
   377      * TEST: { C o = new C(); o.m()I  == 2; }
   358      */
   378      */
   359     public void testPrivateDefaultVsConcrete() {
   379     public void testPrivateVsConcrete() {
   360         TestBuilder b = factory.getBuilder();
   380         TestBuilder b = factory.getBuilder();
   361 
   381 
   362         Interface I = b.intf("I")
   382         Interface I = b.intf("I")
   363                 .defaultMethod("m", "()I")
   383                 .defaultMethod("m", "()I")
   364                     .private_().returns(1).build()
   384                     .private_().returns(1).build()
   383 
   403 
   384     /*
   404     /*
   385      * testPublicOverridePrivate
   405      * testPublicOverridePrivate
   386      *
   406      *
   387      * interface I {
   407      * interface I {
   388      *   default private int m() { return 1; }
   408      *   private int m() { return 1; }
   389      * }
   409      * }
   390      * interface J extends I {
   410      * interface J extends I {
   391      *   default public int m() { return 2; }
   411      *   default public int m() { return 2; }
   392      * }
   412      * }
   393      * class C implements J {}
   413      * class C implements J {}
   431      *
   451      *
   432      * interface I {
   452      * interface I {
   433      *   default public int m() { return 1; }
   453      *   default public int m() { return 1; }
   434      * }
   454      * }
   435      * interface J extends I {
   455      * interface J extends I {
   436      *   default private int m() { return 2; }
   456      *   private int m() { return 2; }
   437      * }
   457      * }
   438      * class C implements J {}
   458      * class C implements J {}
   439      *
   459      *
   440      * TEST: { I o = new C(); o.m()I  == 1; }
   460      * TEST: { I o = new C(); o.m()I  == 1; }
   441      * TEST: { J o = new C(); o.m()I  == IllegalAccessError; } II J.m priv
   461      * TEST: { J o = new C(); o.m()I  == IllegalAccessError; } II J.m priv
   442      * TEST: { C o = new C(); o.m()I  == 1; }
   462      * TEST: { C o = new C(); o.m()I  == 1; }
   443      */
   463      */
   444     /*
       
   445 
       
   446         REFLECTION:
       
   447   Test2_J_C_m                   : FAILED
       
   448     nsk.share.TestFailure: Caught exception as expected, but its type is wrong:
       
   449       expected: java.lang.IllegalAccessError;
       
   450       actual: java.lang.NoSuchMethodException.
       
   451      */
       
   452     public void testPrivateOverrideDefault() {
   464     public void testPrivateOverrideDefault() {
   453         TestBuilder b = factory.getBuilder();
   465         TestBuilder b = factory.getBuilder();
   454 
   466 
   455         Interface I = b.intf("I")
   467         Interface I = b.intf("I")
   456                 .defaultMethod("m", "()I")
   468                 .defaultMethod("m", "()I")
   473 
   485 
   474     /*
   486     /*
   475      * testPrivateReabstract
   487      * testPrivateReabstract
   476      *
   488      *
   477      * interface I {
   489      * interface I {
   478      *   default private int m() { return 1; }
   490      *   private int m() { return 1; }
   479      * }
   491      * }
   480      * interface J extends I {
   492      * interface J extends I {
   481      *   abstract public int m();
   493      *   abstract public int m();
   482      * }
   494      * }
   483      * class C implements J {}
   495      * class C implements J {}
   520      *
   532      *
   521      * interface I {
   533      * interface I {
   522      *   abstract public int m();
   534      *   abstract public int m();
   523      * }
   535      * }
   524      * interface J extends I {
   536      * interface J extends I {
   525      *   default private int m() { return 1; }
   537      *   private int m() { return 1; }
   526      * }
   538      * }
   527      * class C implements J {}
   539      * class C implements J {}
   528      *
   540      *
   529      * TEST: { I o = new C(); o.m()I throws AbstractMethodError }
   541      * TEST: { I o = new C(); o.m()I throws AbstractMethodError }
   530      * TEST: { J o = new C(); o.m()I throws IncompatibleClassChangeError }
   542      * TEST: { J o = new C(); o.m()I throws IllegalAccessError }
   531      * TEST: { C o = new C(); o.m()I throws AbstractMethodError }
   543      * TEST: { C o = new C(); o.m()I throws AbstractMethodError }
   532      */
   544      */
   533     /*
       
   534          REFLECTION:
       
   535   Test1_I_C_m                   : FAILED
       
   536     nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError
       
   537   Test2_J_C_m                   : FAILED
       
   538     nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError
       
   539   Test3_C_C_m                   : FAILED
       
   540     nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError
       
   541      */
       
   542     public void testPrivateOverrideAbstract() {
   545     public void testPrivateOverrideAbstract() {
   543         TestBuilder b = factory.getBuilder();
   546         TestBuilder b = factory.getBuilder();
   544 
   547 
   545         Interface I = b.intf("I")
   548         Interface I = b.intf("I")
   546                 .abstractMethod("m", "()I").build()
   549                 .abstractMethod("m", "()I").build()
   551                     .private_().returns(1).build()
   554                     .private_().returns(1).build()
   552             .build();
   555             .build();
   553 
   556 
   554         ConcreteClass C = b.clazz("C").implement(J).build();
   557         ConcreteClass C = b.clazz("C").implement(J).build();
   555 
   558 
   556         Class expectedClass;
       
   557         if (factory.getExecutionMode().equals("REFLECTION")) {
       
   558             expectedClass = IllegalAccessException.class;
       
   559         } else {
       
   560             expectedClass = IncompatibleClassChangeError.class;
       
   561         }
       
   562 
       
   563         b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done()
   559         b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done()
   564          .test().privateCallSite(J, C, "m", "()I").throws_(expectedClass).done()
   560          .test().privateCallSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done()
   565          .test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done()
   561          .test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done()
   566          .run();
   562          .run();
   567     }
   563     }
   568 
   564 
   569     /*
   565     /*
   570      * testPrivateInheritedDefault
   566      * testPrivateInherited
   571      *
   567      *
   572      * interface I {
   568      * interface I {
   573      *   default private int m() { return 1; }
   569      *   private int m() { return 1; }
   574      * }
   570      * }
   575      * class B implements I {}
   571      * class B implements I {}
   576      * class C extends B {}
   572      * class C extends B {}
   577      *
   573      *
   578      * TEST: { I o = new C(); o.m()I throws IllegalAccessError } II I.m
   574      * TEST: { I o = new C(); o.m()I throws IllegalAccessError } II I.m
   579      *                 -mode reflect throws NoSuchMethodException
   575      *                 -mode reflect throws NoSuchMethodException
   580      * TEST: { B o = new C(); o.m()I throws NoSuchMethodError }
   576      * TEST: { B o = new C(); o.m()I throws NoSuchMethodError }
   581      * TEST: { C o = new C(); o.m()I throws NoSuchMethodError }
   577      * TEST: { C o = new C(); o.m()I throws NoSuchMethodError }
   582      */
   578      */
   583     public void testPrivateInheritedDefault() {
   579     public void testPrivateInherited() {
   584         TestBuilder b = factory.getBuilder();
   580         TestBuilder b = factory.getBuilder();
   585 
   581 
   586         Interface I = b.intf("I")
   582         Interface I = b.intf("I")
   587                 .defaultMethod("m", "()I")
   583                 .defaultMethod("m", "()I")
   588                     .private_().returns(1).build()
   584                     .private_().returns(1).build()
   605         .run();
   601         .run();
   606 
   602 
   607     }
   603     }
   608 
   604 
   609     /*
   605     /*
   610      * testPrivateDefaultVsConcreteInherited
   606      * testPrivateVsConcreteInherited
   611      *
   607      *
   612      * interface I {
   608      * interface I {
   613      *    default private int m() { return 1; }
   609      *    private int m() { return 1; }
   614      * }
   610      * }
   615      * class B {
   611      * class B {
   616      *   public int m() { return 2; }
   612      *   public int m() { return 2; }
   617      * }
   613      * }
   618      * class C extends B implements I {}
   614      * class C extends B implements I {}
   620      * TEST: { I o = new C(); o.m()I  == throws IllegalAccessError; }
   616      * TEST: { I o = new C(); o.m()I  == throws IllegalAccessError; }
   621      *                     -mode reflect throws NoSuchMethodException
   617      *                     -mode reflect throws NoSuchMethodException
   622      * TEST: { B o = new C(); o.m()I  == 2; }
   618      * TEST: { B o = new C(); o.m()I  == 2; }
   623      * TEST: { C o = new C(); o.m()I  == 2; }
   619      * TEST: { C o = new C(); o.m()I  == 2; }
   624      */
   620      */
   625     public void testPrivateDefaultVsConcreteInherited() {
   621     public void testPrivateVsConcreteInherited() {
   626         TestBuilder b = factory.getBuilder();
   622         TestBuilder b = factory.getBuilder();
   627 
   623 
   628         Interface I = b.intf("I")
   624         Interface I = b.intf("I")
   629                 .defaultMethod("m", "()I")
   625                 .defaultMethod("m", "()I")
   630                     .private_().returns(1).build()
   626                     .private_().returns(1).build()
   651     }
   647     }
   652 
   648 
   653     /*
   649     /*
   654      * testPrivateConflict
   650      * testPrivateConflict
   655      *
   651      *
   656      * Conflicting default methods
   652      * Conflicting methods
   657      *
   653      *
   658      * interface I {
   654      * interface I {
   659      *   default private int m() { return 1; }
   655      *   private int m() { return 1; }
   660      * }
   656      * }
   661      * interface J {
   657      * interface J {
   662      *   default public int m() { return 2; }
   658      *   default public int m() { return 2; }
   663      * }
   659      * }
   664      * class C implements I, J {}
   660      * class C implements I, J {}