Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create synthetic fields in java?

  1. How can synthetic fields be created in Java?

  2. Can synthetic fields in java only be created at runtime? If not: Is there a standard-compliant way to this at compile time (without changing some bytes in the class file)

like image 656
MRalwasser Avatar asked Jul 21 '10 10:07

MRalwasser


3 Answers

They're created by the compiler when "oddities" of the language require them. A simple example of this is using an inner class:

public class Test
{
    class Inner
    {
    }
}

The Test.Inner class will have a synthetic field to represent the appropriate instance of the Test class.

We can extend this code slightly to show that field:

import java.lang.reflect.*;

public class Test
{
    public static void main(String[] args)
    {
        for (Field field : Inner.class.getDeclaredFields())
        {
            System.out.println(field.getName() + ": " + field.isSynthetic());
        }
    }

    class Inner
    {
    }
}

With my compiler, that prints:

this$0: true
like image 128
Jon Skeet Avatar answered Nov 12 '22 07:11

Jon Skeet


How can synthetic fields be created in Java?

synthetic field is created by Java compiler automatically, in some specific cases.

Examples:

  • Help process the Java assert keyword - java.awt.AWTKeyStroke.$assertionsDisabled

  • Help process the java this keyword - java.util.AbstractList$Itr.this$0

  • Field in an anonymous inner class - java.util.AbstractList$SubList$1.val$index

  • Help process on Enum fields - java.nio.file.attribute.AclEntryFlag.$VALUES

Can synthetic fields in java only be created at runtime? If not: Is there a standard-compliant way to this at compile time (without changing some bytes in the class file)

The synthetic is generated in compile time by Java compiler. The .class file already contains the ACC_SYNTHETIC flag. Although we can always generate Java fields at runtime.

More Info

  • This article describes the ACC_SYNTHETIC flag in details
  • This link lists all synthetic fields in JDK
like image 27
Happy Avatar answered Nov 12 '22 09:11

Happy


Yes, it's doable, and it's called load-time weaving. Essentially, you will need to define your own ClassLoader that will decide on a class-by-class case whether to do modify a classfile that is bout to be loaded; that means you will need to inspect the binary class that is being loaded, possibly modify it, then pass it on to the JVM for definition/resolving. It's a bit cumbersome, complicated, and prone to ClassCastExceptions (the same class defined in 2 different classloaders will give 2 different classes that are not assignment-compatible).

Note that weaving allows you to do much more: you can add new methods, interfaces, fields, modify the code of existing classes, and more.

There are already tools that can help you - see for example AspectJ as a full-on language modification, or something like BCEL or javassist that allows you to write such weaving tools.

like image 28
Tassos Bassoukos Avatar answered Nov 12 '22 07:11

Tassos Bassoukos