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 Video Library
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
View Events Video Library
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
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

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • How To Get and Set PDF Form Fields in Java
  • Micro Frontends for Quarkus Microservices
  • Building AI Applications With Java and Gradle
  • Demystifying Project Loom: A Guide to Lightweight Threads in Java

Trending

  • Best Practices for Writing Clean Java Code
  • Podman Desktop Review
  • Generative AI: A New Tool in the Developer Toolbox
  • AI for Web Devs: Project Introduction and Setup
  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.47K 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.

Related

  • How To Get and Set PDF Form Fields in Java
  • Micro Frontends for Quarkus Microservices
  • Building AI Applications With Java and Gradle
  • Demystifying Project Loom: A Guide to Lightweight Threads in Java

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

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: