Is there a difference between private, public, package keywords at runtime?

I know that Java has these keywords for defining the scope of variables during development, but I would like to know if this is different when it is in a production environment or just for the interest of an encoder? Thanks.

+7
source share
4 answers

Availability also applies at runtime. If any code tries to access a member that it should not, then an IllegalAccessException or IllegalAccessError . Here is a quick demo:

 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:

Be that as it may, the above program outputs:

 Caught IllegalAccessException Number read: 10 

Without reflection:

When I use the bytecode editor to change

 getfield com/blah/access/AccessTest/publicNumber I 

in the noReflection() to method:

 getfield com/blah/access/AccessTest/secretNumber I 

output:

 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 noted, this behavior may be JVM dependent. I ran it 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) 
+5
source

No, the JVM actually validates and provides runtime visibility.

There are ways to get around this with reflection, but the SecurityManager can also prevent it.

+5
source

Checks are performed at runtime as well as compilation time. There is a whole load of exceptions of this type that can be thrown at runtime, for example, IllegalAccessException :

An IllegalAccessException is thrown when an application tries to reflexively create an instance (except an array), set or receive a field, or call a method, but the current executable method does not have access to the definition of the specified class, field, method, or constructor.

+2
source

Checks are performed at runtime (as well as compilation time). However, these checks, while relatively expensive, are usually performed once per call, and are not significant.

Two exceptions that I can think of:

  • If you are accessing a private member of a class in the same file, you must create an access method (since the JVM does not allow access to a private member from another class, nested or otherwise) t affect performance, as far as you think, since the method can be built-in. What he can do is add the confusing access$100 method to the call stack

  • If you use reflection, the check is performed every time. If you use member.setAccessible(true) , it disables the security check and can make access / call faster even if the member is public.

+1
source

All Articles