javac behavior change in JDK 7 regarding private member access
java, java-7, javac, private-members
Solution
Well, I'm puzzled by this and the only explanation I can adventure is the conjunction of two things.
1_ `getClass()` docs say the following:
The actual result type is `Class<? extends |X|>` where `|X|` is the erasure of the static type of the expression on which `getClass` is called.
2_ One of the incompatibilities introduced in Java 7 is Compiler No Longer Allows Access to Private Members of Type Variables.
So, the compiler is unsure it the cast is made to the base class or a subclass and it blocks accesing a private member, since if the cast were to be assigned to a subclass it would be illegal even if defined in the original parent class, as shown in the following example:
class BaseTest {
private final int i = 1;
void test(Object o) {
if (getClass().isInstance(o)) {
TestAccess to = TestAccess.class.cast(o);
//System.out.println(to.i); // ERROR: i has private access in BaseTest
}
}
}
class TestAccess extends BaseTest{}
So, I guess it's one more of Java quirks due to rules that make more sense in more complex examples.
Problem
This code compiles OK using javac JDK version 1.6.0_33-b03-424, but doesn't compile using javac JDK version 1.7.0_06. ``` public class Test { private final int i = 0; void test(Object o) { if (getClass().isInstance(o)) { System.out.println(getClass().cast(o).i); } } } ``` javac output is: ``` Test.java:6: error: i in Test is defined in an inaccessible class or interface System.out.println(getClass().cast(o).i); ^ 1 error ``` Changing the code to store the result of `getClass.cast()` in a temporary variable allows the program to compile without error. This is easy to work around, but I can't find any rationale for this change in the JLS 7, or any mention of a change like this in the JDK 7 release notes. There is a mention of an access change regarding private members of type parameters to a generic, but that doesn't apply here. Is this a regression in javac? Is it now enforcing a restriction that it wasn't enforcing before?