JDK-8131042 : Private field access: invalid compiler error
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u45
  • Priority: P4
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: windows_8
  • CPU: x86
  • Submitted: 2015-07-12
  • Updated: 2015-09-23
  • Resolved: 2015-09-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.3.9600]

A DESCRIPTION OF THE PROBLEM :
The compiler does not always obey the specification for private field access.

The Java Language Specification, section 6.6.1 [1], says: "Otherwise, the member or constructor is declared private, and access is permitted if and only if it occurs within the body of the top level class (��7.6) that encloses the declaration of the member or constructor."

In the example below (cf. "Steps to Reproduce"), "the top level class that encloses the declaration of the member or constructor" is A. And access occurs within its body, so access must be permitted & the example must compile successfully.

[1] http://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Save the code below to a file named A.java & try to compile it: javac A.java


class A {

    private int a;

    private static class B {
        
        private int b;
        
    }

    private class C extends B {
        
        private int c;
        
        void testAccess() {
			int x = a+b+c;
        }

    }

}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The file compiles successfully.
ACTUAL -
An error occurs:

A.java:16: error: b has private access in B
                        int x = a+b+c;
                                        ^
1 error

REPRODUCIBILITY :
This bug can be reproduced always.


Comments
Producing a compile-time error is correct in this case, I think: per JLS, as private members are not inherited, there is "b" is not a member of the A.C class, so is not in scope at the place it is used, and hence cannot be used. Note that if "super.b" or or "((B) this).b" is used, the access is allowed, so the access rights checks work OK. The issue, I think, is that javac is producing a somewhat confusing error message (for impl. reasons) - I think it would be useful to look if we can produce a better error message in cases like this.
23-09-2015

Checked this for JDK 8u45, 8u60 b23, and 9 ea b72 and could reproduce the issue. (Run attached A.java). Output with JDK 8u45: > javac A.java A.java:16: b has private access in A.B int x = a+b+c; ^ 1 error
13-07-2015