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

Interface with private method can work as a functional interface?

    Details

    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      FULL PRODUCT VERSION :
      java version "9.0.1"
      Java(TM) SE Runtime Environment (build 9.0.1+11)
      Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      17.2.0 Darwin Kernel Version 17.2.0: Fri Sep 29 18:27:05 PDT 2017; root:xnu-4570.20.62~3/RELEASE_X86_64 x86_64


      A DESCRIPTION OF THE PROBLEM :
      The following code is quite confusing, as after casting an anonymous class to its interface it can work as a functional interface (in various constructions actually):

      public class A {
          public static void main(String[] args) {
              Runnable test1 = ((I)(new I() {}))::test; // compiles OK
              Runnable test2 = ((new I() {}))::test; // won't compile
          }

          interface I {
              private void test() {}
          }
      }

      So, Runnable test1 = ((I)(new I() {}))::test; compiles and works okay, while Runnable test2 = ((new I() {}))::test; doesn't compile.

      It seems that it is not a consistent behavior. Either one should be compiled well and another, or both shouldn't be compiled.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile the following code:

      public class A {

          public static void main(String[] args) {
              Runnable test1 = ((I)(new I() {}))::test;
              Runnable test2 = ((new I() {}))::test;
          }

          interface I {
              private void test() {}
          }

      }


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Perhaps, Runnable test2 = ((new I() {}))::test; should be compiled fine in this example.
      ACTUAL -
      Runnable test1 = ((I)(new I() {}))::test; is compiled well
      Runnable test2 = ((new I() {}))::test; is not compiled.



      REPRODUCIBILITY :
      This bug can be reproduced always.

      1. A.java
        0.2 kB
        Fairoz Matte

        Issue Links

          Activity

          Hide
          fmatte Fairoz Matte added a comment -
          Inconsistency in compiler error message started from "JDK-8071453: Allow interface methods to be private"
          This issue is similar to one we have observed in "JDK-8194847: javac generates bad code for private method in interface super call"
          Show
          fmatte Fairoz Matte added a comment - Inconsistency in compiler error message started from " JDK-8071453 : Allow interface methods to be private" This issue is similar to one we have observed in " JDK-8194847 : javac generates bad code for private method in interface super call"
          Hide
          fmatte Fairoz Matte added a comment -
          9.0.4 GA - Fail
          10 ea b37 - Fail

          Result on 10 ea b37
          ==
          -sh-4.2$ /scratch/fairoz/JAVA/jdk10/jdk-10-ea+37/bin/javac A.java
          A.java:4: error: invalid method reference
                  Runnable test2 = ((new I() {}))::test; // won't compile
                                   ^
            compiler message file broken: key=compiler.misc.cant.resolve.args arguments=method, test, , , {4}, {5}, {6}, {7}
          1 error
          ==
          Show
          fmatte Fairoz Matte added a comment - 9.0.4 GA - Fail 10 ea b37 - Fail Result on 10 ea b37 == -sh-4.2$ /scratch/fairoz/JAVA/jdk10/jdk-10-ea+37/bin/javac A.java A.java:4: error: invalid method reference         Runnable test2 = ((new I() {}))::test; // won't compile                          ^   compiler message file broken: key=compiler.misc.cant.resolve.args arguments=method, test, , , {4}, {5}, {6}, {7} 1 error ==
          Hide
          vromero Vicente Arturo Romero Zaldivar added a comment -
          evaluation from Maurizio:
          new I() {} doesn't have same members as I, the latter has a 'test' method but, since test is private it is not inherited by a subclass so the compiler is right in rejecting new I() {}::test but the diagnostic is wrong
          Show
          vromero Vicente Arturo Romero Zaldivar added a comment - evaluation from Maurizio: new I() {} doesn't have same members as I, the latter has a 'test' method but, since test is private it is not inherited by a subclass so the compiler is right in rejecting new I() {}::test but the diagnostic is wrong

            People

            • Assignee:
              vromero Vicente Arturo Romero Zaldivar
              Reporter:
              webbuggrp Webbug Group
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated: