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

6.6.2: Protected accessibility check inconsistent with longstanding javac behavior

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 9
    • 8
    • specification

      Tentatively considering this a spec bug, since the inconsistency is very old, and there's no particular reason javac's approach is worse than JLS's (in fact, in some ways it is nicer). (Eclipse behavior matches javac.)

      6.6.2 claims that a protected method is inaccessible if 1) the invocation is in a different package, and either 2) the invocation is not from a subclass of the declaring class, or 3) the invocation has an expression-/variable-qualified form and the qualifying type is not a subclass of the invoking class.

      Javac implements #3 differently: the method is inaccessible if it is not declared static and the qualifying type is not a subclass of the invoking class. The syntactic form of the invocation is irrelevant.

      To illustrate:

      package p1;
      public class A {
        protected void m(String s) { System.out.println("instance"); }
        protected static void m(Object o) { System.out.println("static"); }
      }

      package p2;
      public class B extends p1.A {}

      package p2;
      public class C extends p1.A {
        public static void main(String... args) {
          test(new p1.A(), new B(), new C());
        }
        
        public static void test(p1.A a, B b, C c) {
          p1.A.m("x"); // *** JLS: error, malformed instance invocation; javac: print "static" ***
          B.m("x"); // *** JLS: error, malformed instance invocation; javac: print "static" ***
          C.m("x"); // JLS: error, malformed instance invocation; javac: error invoking instance
          
          a.m("x"); // *** JLS: error, no accessible methods; javac: print "static" ***
          b.m("x"); // *** JLS: error, no accessible methods; javac: print "static" ***
          c.m("x"); // JLS: print "instance"; javac: print "instance"
        }
      }

      JLS text is essentially the same since the 1st edition.

      javac behavior is the same in 6, 7, and 8.

      ecj behavior is the same in 3.5, 3.6, 3.7, 3.8, and 3.9.

            abuckley Alex Buckley
            dlsmith Dan Smith
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: