RubenGees RubenGees - 2 months ago 10
Java Question

Visibility of Methods and their cost

I recently read this article by Jake Wharton. This is targeted at Android, but also perfectly valid for java I think.

Consider the following code:

public class A {

private String someField = "abc";

class B {

public void doSomething() {
System.out.println(someField);
}

}
}


We have a simple class A and an inner class B (This has a reference to A and can acccess its members). Class B is accessing the field
someField
in A even though it is private. According to the article, this is done by the compiler generating
synthetic accessor methods
which allow the inner class to access the field.

Now my way more basic question: Why does the compiler even care about visiblities when the code is compiled? As we have seen in this example, a new method is generated, which basically just introduces overhead.

Visibilities are a great thing for architecting good software, but if the compiler is done checking that everything is correct according to the declared visibilies, why not optimize those methods away (E.g. just taking everything for being public and allow calls to it)?

First I thought this was due to security reasons, but reflection allows the access of all fields, not caring for visibility as far as I know.

This might be a basic misunderstanding of me, if so, I would be happy if someone could explain it to me.

Answer

Why does the compiler even care about visiblities when the code is compiled?

The JVM doesn't allows access to private methods/constructors/fields outside a class. It has no special rule for nested classes which were added after this rule was designed. Instead the compiler adds accessor methods so the language can support a means of access the JVM doesn't.

As we have seen in this example, a new method is generated, which basically just introduces overhead.

Only if the method isn't called very much and isn't optimised.

Adding any simple method (On Hotspot, any method of 35 bytes or less) will be inlined very quickly and has no impact on performance (except if the maximum inline level is reached)

why not optimize those methods away

It does this at runtime so that previous rules continue to be enforced.

reflection allows the access of all fields, not caring for visibility as far as I know.

Though not by default, you have to explicitly want this as an option and not have a SecurityManager which prevents it.