I know that the Java have these serval keywords to identify the variable scope during development, but I would like to know whether this is different when it is in a production environment or just for coder interest? Thanks.
Accessibility is enforced at runtime as well. If some code tries to access a member that it shouldn't, then IllegalAccessException
or IllegalAccessError
is thrown. Here's a quick demonstration:
public class AccessTest {
public int publicNumber;
private int secretNumber;
}
public class Client {
public static void main(String[] args) throws Exception {
reflection();
noReflection();
}
private static void noReflection() throws IllegalAccessException, NoSuchFieldException {
int a = new AccessTest().publicNumber;
// ^^^^^^^^^^^^
// To be changed to secretNumber in bytecode editor after compilation
System.out.println("Number read: " + a);
}
private static void reflection() throws IllegalAccessException, NoSuchFieldException {
AccessTest instance = new AccessTest();
AccessTest.class.getDeclaredField("publicNumber").get(instance); // <-- Works
try {
AccessTest.class.getDeclaredField("secretNumber").get(instance); // <-- Throws IllegalAccessException
} catch (IllegalAccessException e) {
System.out.println("Caught IllegalAccessException");
}
}
}
As it is, the above program outputs:
Caught IllegalAccessException
Number read: 10
When I use a bytecode editor to change
getfield com/blah/access/AccessTest/publicNumber I
in method noReflection()
to:
getfield com/blah/access/AccessTest/secretNumber I
the output is:
Caught IllegalAccessException
Exception in thread "main" java.lang.IllegalAccessError: tried to access field com.blah.access.AccessTest.secretNumber from class com.blah.access.Client
at com.blah.access.Client.noReflection(Client.java)
at com.blah.access.Client.main(Client.java:12)
As Michael mentioned this behavior may be JVM dependent. I ran this on
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)
No, the JVM actually checks and enforces visibility at runtime.
There are ways to get around that using reflection, but a SecurityManager can forbid that, too.
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