Yes, we're now running our Black Friday Sale. All Access and Pro are 33% off until 2nd December, 2025:
Introduction to Objenesis
Last updated: April 16, 2025
1. Introduction
The object creation process in Java most often involves the constructor’s execution. However, in some cases, we may need to create objects without enforcing constructor logic.
For example, we may want to mock dependencies during unit testing or manage the object lifecycle within a framework. Other examples are when working with legacy code with complex constructor dependencies or in specific scenarios of deserialization.
To help us with such use cases, we have Objenesis – a small Java library that allows us to instantiate objects from classes without calling their constructors. It’s useful for libraries and frameworks that need to create objects dynamically, bypassing constructor execution entirely.
In this tutorial, we’ll explore how Objenesis works, how to use it in our projects, and its practical applications through hands-on examples.
2. Traditional Object Creation in Java
We know Java always executes one of the constructors when we create an object using the new keyword.
Let’s create the User class to illustrate this standard object creation in Java:
public class User {
private String name;
public User() {
System.out.println("User constructor is called!");
}
// getters and setters
}
Here, we’ve included a print statement in the default constructor of the User class, allowing us to confirm that the constructor is invoked when we create an instance of the User class:
User user = new User();
Upon execution of this code, we can observe that the message User constructor is called! printed on the console, thereby confirming that the constructor was indeed used in the creation of the User object.
3. How Objenesis Works?
Objenesis doesn’t rely on the new keyword, followed by a call to one of the class’s constructors to create an object. Instead, it uses low-level JVM mechanisms to allocate memory and instantiate the object while bypassing constructors entirely.
Internally, Objenesis tries different instantiator strategies until it’s successful, depending on the JVM vendor and version.
3.1. Setup
We’ll add the latest org.objenesis Maven dependency to our pom.xml:
<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>3.4</version>
</dependency>
This library provides the Objenesis interface with two major implementations:
- ObjenesisStd: the standard, thread-safe implementation that tries different strategies (relying on vendor and version of JVM) when creating an object
- ObjenesisSerializer: a specialized non-thread-safe implementation optimized for serialization frameworks
Additionally, Objenesis provides the ObjenesisHelper utility class that simplifies object instantiation using the above implementations.
3.2. Object Creation Using ObjenesisStd
Let’s modify our User class to restrict the use of the constructor entirely:
public class User implements Serializable {
private String name;
public User() {
throw new RuntimeException("User constructor should not be called!");
}
// getters and setters
}
Here, we’ve thrown a RuntimeException inside the default constructor to ensure it’s never called in our tests.
Then, let’s create the object of the User class using the ObjenesisStd class without invoking the constructor:
Objenesis objenesis = new ObjenesisStd();
User user = objenesis.newInstance(User.class);
assertNotNull(user);
user.setName("Harry Potter");
assertEquals("Harry Potter", user.getName());
Here, we created an instance of the ObjenesisStd class, a thread-safe implementation of Objenesis. Then, we used it to instantiate the User object without calling its constructor.
The assertNotNull() check ensures that the object is successfully created.
To confirm that the object behaves normally, we set the user’s name using the setName() method and retrieve it with the getName() method, confirming that its properties and behaviors remain intact.
3.3. Object Creation Using ObjenesisSerializer
Similarly, we can utilize the ObjenesisSerializer class to create the User object using a serialization-based instantiation strategy:
Objenesis objenesis = new ObjenesisSerializer();
User user = objenesis.newInstance(User.class);
assertNotNull(user);
user.setName("Harry Potter");
assertEquals("Harry Potter", user.getName());
This implementation of the Objenesis interface uses a method similar to deserialization to create new objects.
The underlying object creation mechanism relies on the principles of serialization. Therefore, we should make sure that our class implements the Serializable interface when using the ObjenesisSerializer to create an object. Otherwise, it’ll likely result in an exception.
3.4. Object Creation Using ObjenesisHelper
Additionally, the Objenesis library provides the ObjenesisHelper utility class, which simplifies object creation using both the standard and serialization strategies.
Let’s examine its usage of the standard strategy:
User user = ObjenesisHelper.newInstance(User.class);
assertNotNull(user);
user.setName("Harry Potter");
assertEquals("Harry Potter", user.getName());
Similarly, we can use the serialization strategy:
User user = ObjenesisHelper.newSerializableInstance(User.class);
assertNotNull(user);
user.setName("Harry Potter");
assertEquals("Harry Potter", user.getName());
So, the ObjenesisHelper class offers a convenient and preferred way to use Objenesis, as it encapsulates the explicit creation of ObjenesisStd or ObjenesisSerializer instances for common use cases.
4. Advanced Use Cases
Objenesis supports many advanced use cases, especially when standard object creation isn’t feasible.
Serialization frameworks, such as Kryo, internally use Objenesis to create objects during deserialization without invoking their constructors. This is crucial for performance and for handling scenarios where the serialized data doesn’t align with the constructor’s requirements.
Mocking frameworks, like Mockito and EasyMock, often utilize Objenesis internally to create mock objects or proxies for testing purposes. When we create a mock of a class, the mocking framework needs to instantiate a proxy object that can intercept method calls and record interactions. Objenesis provides a clean way to create these proxy instances without triggering the potentially complex or dependency-laden constructors of the original class.
Normally, final classes or classes with private constructors are extremely difficult to instantiate reflectively. Objenesis bypasses this restriction, enabling instantiation even when a constructor is private or the class is final.
Some lightweight or custom-built dependency injection frameworks may use Objenesis to instantiate beans or service classes where constructor injection is impractical or not desirable, allowing property-based injection without invoking constructors.
In performance-critical applications, we might want to clone or reuse objects without paying the cost of full reinitialization. Objenesis can help create a fresh instance that we populate manually, skipping expensive constructor logic.
5. Best Practices
Objenesis offers a handy alternative for object instantiation without involving a constructor. However, it’s advised to use it cautiously and understand its implications.
Overuse or misuse can lead to unexpected behavior and maintainability challenges. Let’s see some recommended best practices:
- Prefer constructors: we should utilize constructors for regular object creation and use Objenesis only when necessary to bypass constructor invocation
- We should be mindful of security restrictions: environments like Java Security Manager or containerized applications may block Objenesis due to its low-level object instantiation mechanisms
- Leverage framework integration with Objenesis: when using frameworks like Mockito or Kryo, we should let them handle Objenesis internally instead of invoking it directly
- Handling of uninitialized objects: since Objenesis skips constructor logic, we should be more careful in dealing with default-initialized fields, as they may lead to unexpected behavior if not properly handled
- Test instantiated objects: we must ensure that the object created with Objenesis is tested thoroughly – to confirm all properties and behaviors remain intact
- Document its usage clearly: we should document the usage of Objenesis and the associated object initialization strategy to improve maintainability for other developers
6. Conclusion
In this article, we’ve explored the Objenesis library, which lets us create objects without invoking constructors, making it useful for serialization, mocking, and proxy frameworks.
We’ve explored how it works, set it up in a project, and learned about its capabilities with real-world examples. However, while Objenesis is powerful, we should use it only when necessary to avoid unintended side effects. Additionally, we looked at a few advanced use cases and best practices.
The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.















