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?
To run the program (again using the Java SDK) type: % java Hello. This command should produce the output: Hello World! The java command is the Java interpreter; it runs the Java Virtual Machine. You pass java the name of the class that you want to run.
DESCRIPTION. The javac tool reads class and interface definitions, written in the Java programming language, and compiles them into bytecode class files. It can also process annotations in Java source files and classes.
In order compile all Java source files in a given module, we actually need 3 options: "--module <module-name>": Specify which module to compile. "-d <directory>": Specify where to place generated class files. "--module-source-path <path-list>": Specify where to find input source files of required modules.
The value that you want to add is most likely C:\Program Files\Java\jdk-14.0. 2\bin if you are installing "JDK 14.0. 2". This is the location where the Java compiler ('java.exe') was installed in your file system.
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 whichgetClass
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With