Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any difference between private, public, package keywords during runtime?

Tags:

java

scope

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.

like image 981
DNB5brims Avatar asked Mar 15 '12 07:03

DNB5brims


2 Answers

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");
        }
    }
}

With reflection:

As it is, the above program outputs:

Caught IllegalAccessException
Number read: 10

Without reflection:

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)
like image 154
oksayt Avatar answered Oct 12 '22 02:10

oksayt


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.

like image 29
Thilo Avatar answered Oct 12 '22 02:10

Thilo