Effects of Java’s Synthetic Accessor Methods in Android

Bob
Bob
Nov 5, 2016 · 3 min read
Image for post
Image for post
Image Credit: MemeMaker

Does the following Java code compile?

// Outer.java 
public class Outer {
private static void doSomething() {
}

private class Nested {
private void execute() {
Outer.doSomething();
}
}
}

Yes. Of course. Java does support nested class and the nested class can access the private members of the outer class. But, does Java has true nesting classes? Let’s explore more.

$ javac Outer.java$ ls 
Outer$Nested.class
Outer.class
Outer.java

The compiler compiles the Outer.java class into two separate classes: Outer.class and Outer$Nested.class. So that is not true class nesting.

Now the obvious question arises, “If Java does not support true nesting then how one class can access the private member of another class?”. The all mighty Java solves this problem under the hood by creating a synthetic access method.

Let’s look into the Outer class,

$ javap -p -c Outer public class Outer { 
public Outer();
Code: <removed>
private static void doSomething();
Code: <removed>
static void access$000();
Code:
0: invokestatic #1 // Method doSomething:
3: return
}

Look closely in the above snippet. The compiler has created a package-scoped static method named “access$…” on behalf of us. That method just forwards the method invocation to the actual private method. That’s one waste and literally unused method created for us.

Anonymous class is also a nested class, but with no name. So it is very likely that these synthetic methods are created when we use the click listeners in our app.

Let’s say, we access a few private fields inside the click listener,

private String a; 
private String b;
private String c;
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
// click action
a = “a”;
b = “b”
c = “c”;
}
}

Now three unwanted synthetic methods are created.

Even if the same private field is accessed from the nested class as ‘x’ different actions, ‘x’ synthetic methods are created.

private int count = 0; button.setOnClickListener(new OnClickListener() { 
@Override
public void onClick(View view) {
// click action
count++;
count — ;
++count;
— count;
}
}

This code block creates four synthetic methods.

Drawbacks of Synthetic methods in Android:

A few bunch of extra methods might seem trivial. But it quickly adds up to a few thousands of unwanted methods as we have these nested/ anonymous classes everywhere in our code, and in other libraries we use.

1.Dex method reference limit
We all know that every Android app has 65,536 methods limit (without multidex). So it is not wise to waste few thousand methods as unwanted synthetic methods.

2.Performance:
Direct field access is about 7 times faster than invoking a getter method . Unknowingly we might be using these synthetic methods to access the fields where the direct filed access would have been much faster.

How to fix:
Hunt all the private members that are accessed from nested class and edit to package scope. ​​:P

There is an Intellij inspection that shows a warning for this private member access. To enable it in Android Studio, go to: Preferences > Editor > Inspections > Java > J2ME issues > Private member access between outer and inner classes

Do not ignore the warning. Fixing this as and when it’s encountered is a better approach than editing the entire application.

Reference:
https://www.youtube.com/watch?v=WALV33rWye4

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store