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
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Java 27 Makes G1 the Default Everywhere: How to Test Your Small Containers Before You Upgrade
  • Stop Writing Database Migration Scripts: Declarative Schema Sync for Java
  • Searching Kafka Without an Index: Lessons From Building Message Search for Kafdrop
  • ScyllaDB in Enterprise Java: High-Performance NoSQL With Eclipse JNoSQL

Trending

  • Designing the Runtime Layer for Stateful AI Agents: Where Agent Substrate Fits
  • Beyond the Wall of Charts: How Advanced Observability Displaced the Telemetry Dashboard
  • Beyond State Consistency: Preventing Stale Decisions in AI Agent Systems
  • Your Event Storming Is Not Your Software Design

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Java
  4. Generating Classes at Runtime and Invoking Their Methods With and Without the Use of Reflection in Java 8 and Later

Generating Classes at Runtime and Invoking Their Methods With and Without the Use of Reflection in Java 8 and Later

In this article, take a look at generating classes at runtime and invoking their methods with and without the use of reflection in Java 8 and later.

By 
Stoffer Khan
·
Updated May. 22, 20 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
28.2K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

The generation of classes at runtime is an advanced topic that requires a lot of knowledge that can be reduced if you use particular libraries that perform the most complex functions to accomplish this task.
So, for this purpose, we can use the ClassFactory component and the sources generating components of the Burningwave Core library. Once the sources have been set in UnitSourceGenerator objects, they must be passed to loadOrBuildAndDefine method of ClassFactory with the ClassLoader where you want to define newly generated classes.

This method performs the following operations: tries to load all the classes present in the UnitSourceGenerator through the class loader, if at least one of these is not found it proceeds to compile all the UnitSourceGenerators and uploading their classes on class loader: in this case, keep in mind that if a class with the same name was previously loaded by the class loader, the compiled class will not be uploaded.

Once the classes have been compiled and loaded, it is possible to invoke their methods in several ways, as shown at the end of the example below.

Java
x
100
 
1
package org.burningwave.core.examples.classfactory;
2
3
import static org.burningwave.core.assembler.StaticComponentContainer.Constructors;
4
5
import java.lang.reflect.Modifier;
6
import java.time.LocalDateTime;
7
import java.time.ZoneId;
8
import java.util.Date;
9
10
import org.burningwave.core.Virtual;
11
import org.burningwave.core.assembler.ComponentContainer;
12
import org.burningwave.core.assembler.ComponentSupplier;
13
import org.burningwave.core.classes.AnnotationSourceGenerator;
14
import org.burningwave.core.classes.ClassFactory;
15
import org.burningwave.core.classes.ClassSourceGenerator;
16
import org.burningwave.core.classes.FunctionSourceGenerator;
17
import org.burningwave.core.classes.GenericSourceGenerator;
18
import org.burningwave.core.classes.TypeDeclarationSourceGenerator;
19
import org.burningwave.core.classes.UnitSourceGenerator;
20
import org.burningwave.core.classes.VariableSourceGenerator;
21
22
public class RuntimeClassExtender {
23
24
    @SuppressWarnings("resource")
25
    public static void execute() throws Throwable {
26
        UnitSourceGenerator unitSG = UnitSourceGenerator.create("packagename").addClass(
27
            ClassSourceGenerator.create(
28
                TypeDeclarationSourceGenerator.create("MyExtendedClass")
29
            ).addModifier(
30
                Modifier.PUBLIC
31
            //generating new method that override MyInterface.convert(LocalDateTime)
32
            ).addMethod(
33
                FunctionSourceGenerator.create("convert").setReturnType(
34
                    TypeDeclarationSourceGenerator.create(
35
                        Comparable.class
36
                    ).addGeneric(
37
                        GenericSourceGenerator.create(Date.class)
38
                    )
39
                )
40
                .addParameter(VariableSourceGenerator.create(LocalDateTime.class, "localDateTime"))
41
                .addModifier(Modifier.PUBLIC)
42
                .addAnnotation(AnnotationSourceGenerator.create(Override.class))
43
                .addBodyCodeRow(
44
                    "return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());"
45
                ).useType(ZoneId.class)
46
            ).addConcretizedType(
47
                MyInterface.class
48
            ).expands(ToBeExtended.class)
49
        );
50
        System.out.println("\nGenerated code:\n" + unitSG.make());
51
        //With this we store the generated source to a path
52
        unitSG.storeToClassPath(System.getProperty("user.home") + "/Desktop/bw-tests");
53
        ComponentSupplier componentSupplier = ComponentContainer.getInstance();
54
        ClassFactory classFactory = componentSupplier.getClassFactory();
55
        //this method compile all compilation units and upload the generated classes to default
56
        //class loader declared with property "class-factory.default-class-loader" in 
57
        //burningwave.properties file (see "Overview and configuration").
58
        //If you need to upload the class to another class loader use
59
        //loadOrBuildAndDefine(LoadOrBuildAndDefineConfig) method
60
        Class<?> generatedClass = classFactory.loadOrBuildAndDefine(
61
            unitSG
62
        ).get(
63
            "packagename.MyExtendedClass"
64
        );
65
        ToBeExtended generatedClassObject =
66
            Constructors.newInstanceOf(generatedClass);
67
        generatedClassObject.printSomeThing();
68
        System.out.println(
69
            ((MyInterface)generatedClassObject).convert(LocalDateTime.now()).toString()
70
        );
71
        //You can also invoke methods by casting to Virtual (an interface offered by the
72
        //library for faciliate use of runtime generated classes)
73
        Virtual virtualObject = (Virtual)generatedClassObject;
74
        //Invoke by using reflection
75
        virtualObject.invoke("printSomeThing");
76
        //Invoke by using MethodHandle
77
        virtualObject.invokeDirect("printSomeThing");
78
        System.out.println(
79
            ((Date)virtualObject.invokeDirect("convert", LocalDateTime.now())).toString()
80
        );
81
    }   
82
83
    public static class ToBeExtended {
84
85
        public void printSomeThing() {
86
            System.out.println("Called method printSomeThing");
87
        }
88
89
    }
90
91
    public static interface MyInterface {
92
93
        public Comparable<Date> convert(LocalDateTime localDateTime);
94
95
    }
96
97
    public static void main(String[] args) throws Throwable {
98
        execute();
99
    }
100
}
Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • Java 27 Makes G1 the Default Everywhere: How to Test Your Small Containers Before You Upgrade
  • Stop Writing Database Migration Scripts: Declarative Schema Sync for Java
  • Searching Kafka Without an Index: Lessons From Building Message Search for Kafdrop
  • ScyllaDB in Enterprise Java: High-Performance NoSQL With Eclipse JNoSQL

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook