DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
  1. DZone
  2. Coding
  3. Java
  4. Java Secret: Generated methods

Java Secret: Generated methods

Peter Lawrey user avatar by
Peter Lawrey
·
Jul. 20, 11 · Interview
Like (0)
Save
Tweet
Share
13.32K Views

Join the DZone community and get the full member experience.

Join For Free

 The Java compiler generates extra methods which appear in stack traces. These can be confusing at first. What are they and why do they exist?

The access model in the JVM

The access model in the JVM has not changed significantly since version 1.0. However, Java 5.0 added features such as inner/nested classes and convariant return types which were not in the original design. So how are they supported?

The issue with nested classes

Nested classes can access private methods and fields of an outer class. However the JVM does not support this so the compiler generates methods as a workaround.

Private Methods


In this example, the inner class calls a private method init() of the outer class.

public class PrivateMethod { // line 4
    private void init() {
        throw new UnsupportedOperationException(); // line 6
    };

    class Inner {
        Inner() {
            init();
        }
    }

     public static void main(String... args) {
        PrivateMethod pm = new PrivateMethod();
        Inner inner = pm.new Inner();
    }
}

So what does the stack trace look like when we run this?

Exception in thread "main" java.lang.UnsupportedOperationException
 at com.google.code.java.core.javac.generated.PrivateMethod.init(PrivateMethod.java:6)
 at com.google.code.java.core.javac.generated.PrivateMethod.access$000(PrivateMethod.java:4)
 at com.google.code.java.core.javac.generated.PrivateMethod$Inner.(PrivateMethod.java:11)
 at com.google.code.java.core.javac.generated.PrivateMethod.main(PrivateMethod.java:17)

In the stack trace there is a method called access$000 on line 4 which is the first line of the class. Is this a real method? What do we see in the byte code?

$ javap -c -private -classpath . com.google.code.java.core.javac.generated.PrivateMethod

static void <b>access$000</b>(com.google.code.java.core.javac.generated.PrivateMethod);
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method init:()V
   4:   return

$ javap -c -private -classpath . com.google.code.java.core.javac.generated.PrivateMethod\$Inner
Compiled from "PrivateMethod.java"
public class com.google.code.java.core.javac.generated.PrivateMethod$Inner extends java.lang.Object{
final com.google.code.java.core.javac.generated.PrivateMethod this$0;

com.google.code.java.core.javac.generated.PrivateMethod$Inner(com.google.code.java.core.javac.generated.PrivateMethod);
  Code:
   0:   aload_0
   1:   aload_1
   2:   putfield        #1; //Field this$0:Lcom/google/code/java/core/javac/generated/PrivateMethod;
   5:   aload_0
   6:   invokespecial   #2; //Method java/lang/Object."":()V
   9:   aload_1
   10:  invokestatic    #3; //Method com/google/code/java/core/javac/generated/PrivateMethod.
                        <b>access$000</b>:(Lcom/google/code/java/core/javac/generated/PrivateMeth
   13:  return

}
The compiler has added a static method which is not private so the Inner class can access the private method of the outer class indirectly.

Private Fields

Private fields are accessed via a getter and setter, but the compiler can generate methods for assignment operations such as ++ and *=
public class PrivateField {
    private int num = 0;

    public class Inner {
        public void set(int n) {
            num = n;
        }

        public int get() {
            return num;
        }

        public void increment() {
            num++;
        }

        public void multiply(int n) {
            num *= n;
        }
    }
}
Compiles with four generated methods, one for each of get, set, ++ and *=
$ javap -c -private -classpath . com.google.code.java.core.javac.generated.PrivateField
<b>setter</b>
static int access$002(com.google.code.java.core.javac.generated.PrivateField, int);
  Code:
   0:   aload_0
   1:   iload_1
   2:   dup_x1
   3:   putfield        #1; //Field num:I
   6:   ireturn

<b>getter</b>
static int access$000(com.google.code.java.core.javac.generated.PrivateField);
  Code:
   0:   aload_0
   1:   getfield        #1; //Field num:I
   4:   ireturn

increment ++
static int access$008(com.google.code.java.core.javac.generated.PrivateField);
  Code:
   0:   aload_0
   1:   dup
   2:   getfield        #1; //Field num:I
   5:   dup_x1
   6:   iconst_1
   7:   iadd
   8:   putfield        #1; //Field num:I
   11:  ireturn

multiplier *=
static int access$028(com.google.code.java.core.javac.generated.PrivateField, int);
  Code:
   0:   aload_0
   1:   dup
   2:   getfield        #1; //Field num:I
   5:   iload_1
   6:   imul
   7:   dup_x1
   8:   putfield        #1; //Field num:I
   11:  ireturn

Covariant return types

Covariant return types is a feature which was added to Java 5.0 but isn't supported in the JVM. For this reason, the compiler generates a method which overrides all the super methods and their return types.
public class CovariantReturnTypeA {
    public Object method() { return 1L; }
}

public class CovariantReturnTypeB extends CovariantReturnTypeA {
    public Number method() { return 2.0; }
}

public class CovariantReturnTypeC extends CovariantReturnTypeB {
    public Integer method() { return 3; }
}

The last method() overrides the method which returns Number and the method which returns Object. To implement this, the compile generates a method with the same signature which calls the method which returns Integer
$ javap -c -private -classpath . com.google.code.java.core.javac.generated.CovariantReturnTypeC

public java.lang.Integer method();
  Code:
   0:   iconst_3
   1:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   4:   areturn

public java.lang.Number method();
  Code:
   0:   aload_0
   1:   invokevirtual   #3; //Method method:()Ljava/lang/Integer;
   4:   areturn

public java.lang.Object method();
  Code:
   0:   aload_0
   1:   invokevirtual   #3; //Method method:()Ljava/lang/Integer;
   4:   areturn
There are three implementations of method() in the byte code.

Performance implications

The performance implications for Java Standard Edition are small as these methods can be inlined and effectively have no impact. In Java Mobile Edition, this might not be the case.

They can cause some confusion and if this is a problem you can make the fields/methods package-local instead and the generated methods will go away.

From http://vanillajava.blogspot.com/2011/07/java-secret-generated-methods.html

Java (programming language)

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Steel Threads Are a Technique That Will Make You a Better Engineer
  • Building a Real-Time App With Spring Boot, Cassandra, Pulsar, React, and Hilla
  • Spring Boot, Quarkus, or Micronaut?
  • Real-Time Analytics for IoT

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: