To create an object without the new keyword in Java, we call a constructor through reflection or a method handle, copy an existing object with clone() or deserialization, or call a factory method that runs new for us. Only clone(), deserialization and the internal Unsafe.allocateInstance() create an object without running its constructor.
Application code uses new almost everywhere. The other ways matter in frameworks and libraries, which create objects of classes they only know by name, copy objects, or rebuild them from bytes, and in interviews, where the question tests how well we know object creation.
The following example creates four Book objects without writing new Book(…). The Book class is defined in section 1.
Book byReflection = Book.class.getDeclaredConstructor(String.class).newInstance("Dune"); // Dune
Book byClone = byReflection.clone(); // Dune
Book byFactory = Book.of("Emma"); // Emma
Supplier<Book> maker = Book::new;
Book bySupplier = maker.get(); // untitled
Notice that reflection, the factory method and the Supplier still run a Book constructor, whereas clone() copies the fields without one. We go through seven ways in total, check which ones work on Java 25 and which APIs are deprecated, and compare them in one table.
1. What new Does and What the Alternatives Skip
The expression new Book(“Dune”) does three things. The JVM allocates memory for the object, sets every field to its default value, such as null or 0, and runs the constructor, which assigns the real values. The alternatives differ in which of these steps they keep.

Every example uses one small class. It counts its constructor calls in a static field, so we can see which ways run a constructor, and it implements Cloneable and Serializable for the copy-based ways.
class Book implements Cloneable, Serializable {
static int constructorCalls = 0;
String title;
public Book() {
this("untitled");
}
public Book(String title) {
this.title = title;
constructorCalls++;
}
static Book of(String title) {
return new Book(title);
}
@Override
public Book clone() {
try {
return (Book) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e); // cannot happen, Book is Cloneable
}
}
@Override
public String toString() {
return title;
}
}
2. Reflection with Constructor.newInstance()
Reflection finds a constructor at runtime and calls it with Constructor.newInstance(). We use it when the class is known only at runtime, for example from a configuration file, and it is how most dependency injection containers create beans.
Book reflected = Book.class.getDeclaredConstructor().newInstance(); // untitled
Object list = Class.forName("java.util.ArrayList").getDeclaredConstructor().newInstance(); // []
The older Class.newInstance() method has been deprecated since Java 9, and the replacement is getDeclaredConstructor().newInstance(). The old method rethrows any exception from the constructor, including checked exceptions that the compiler never sees, whereas the replacement wraps them in an InvocationTargetException. The Class.forName() and ClassLoader.loadClass() methods only load a class, so they always need one of these calls to create the object.
Reflection respects access rules. A private constructor needs setAccessible(true), and that call fails for classes in modules that do not open their packages to our code, such as java.base.
Constructor<String> hidden = String.class.getDeclaredConstructor(byte[].class, byte.class);
hidden.setAccessible(true); // InaccessibleObjectException: java.base does not open java.lang
Reflection also refuses some classes outright. An abstract class or an interface has nothing to instantiate, and enum constants cannot be created reflectively, which is why an enum is the safest singleton.
3. Method Handles with findConstructor()
A method handle is a typed reference to a method or constructor that we can call like a function, added in Java 7 in the java.lang.invoke package. MethodHandles.Lookup.findConstructor() returns a handle to a constructor. A handle stored in a static final field is a constant for the JIT compiler, so it can inline calls through the handle.
static Book newBookViaHandle(String title) {
try {
MethodHandle ctor = MethodHandles.lookup()
.findConstructor(Book.class, MethodType.methodType(void.class, String.class));
return (Book) ctor.invoke(title);
} catch (Throwable t) {
throw new IllegalStateException("cannot create Book", t);
}
}
Book viaHandle = newBookViaHandle("Ivanhoe"); // Ivanhoe
The method type always has void as its return type, because constructors return nothing, and the parameter types pick the constructor. The invoke() method declares Throwable, so a helper method like newBookViaHandle() keeps that catch block out of the calling code.
4. Copying an Object with clone()
The Object.clone() method allocates a new object of the same class and copies every field value, without calling a constructor. The class must implement Cloneable, otherwise clone() throws CloneNotSupportedException, and it must override clone() as public, because the version in Object is protected.
int callsBeforeClone = Book.constructorCalls;
Book original = Book.of("Persuasion");
Book cloned = original.clone();
boolean differentObject = cloned != original; // true
int cloneCalls = Book.constructorCalls - callsBeforeClone; // 1, only Book.of() ran a constructor
The copy is shallow, so a field that refers to a list or another object refers to the same instance in both copies. For classes we design ourselves, a copy constructor or a static copyOf() method is clearer, as our guide to object cloning explains.
5. Deserialization with ObjectInputStream
Deserialization rebuilds an object from bytes that serialization wrote earlier. The ObjectInputStream class creates the object and sets the fields from the stream, without running the constructor of the Serializable class. It runs only the no-argument constructor of the first superclass that is not Serializable, which is Object for our Book.
static <T extends Serializable> T roundTrip(T object) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (ObjectOutputStream out = new ObjectOutputStream(bytes)) {
out.writeObject(object);
}
try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) {
@SuppressWarnings("unchecked")
T copy = (T) in.readObject();
return copy;
}
}
Book saved = Book.of("Middlemarch");
int callsBeforeRead = Book.constructorCalls;
Book restored = roundTrip(saved); // Middlemarch
int readCalls = Book.constructorCalls - callsBeforeRead; // 0, no constructor ran
Records are the exception. Java deserializes a record through its canonical constructor, so the validation in that constructor runs on every read. Deserializing bytes from an untrusted source is dangerous, because a crafted stream can create objects that the constructors would have rejected. If the app must read such data, it sets an ObjectInputFilter that allows only the expected classes.
6. Factory Methods, Suppliers and Builders
A static factory method, a method reference such as Book::new, and a builder create objects without a new expression at the call site. They still run a constructor inside, or they return a cached object, which is something new can never do.
List<String> genres = List.of("drama", "poetry"); // [drama, poetry]
LocalDate release = LocalDate.of(2026, 3, 14); // 2026-03-14
boolean cached = Integer.valueOf(127) == Integer.valueOf(127); // true, same cached object
Optional<Book> maybe = Optional.of(Book.of("Emma")); // Optional[Emma]
Factory methods are the right choice in application code. The class keeps control over creation, can return a subtype or a cached instance, and gives the creation a name, such as LocalDate.of() or List.copyOf(). The factory pattern takes the idea further with a separate factory class.
7. Unsafe.allocateInstance() Without Any Constructor
The internal class sun.misc.Unsafe in the jdk.unsupported module can allocate an object and skip every constructor, so all fields keep their default values. Libraries that must skip constructors rely on it or on the similar internal ReflectionFactory class, for example Objenesis, which Mockito uses to create mocks of classes whose constructors need arguments.
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
int callsBeforeUnsafe = Book.constructorCalls;
Book raw = (Book) unsafe.allocateInstance(Book.class); // null, title never set
int unsafeCalls = Book.constructorCalls - callsBeforeUnsafe; // 0
On Java 25, allocateInstance() still works and is not deprecated. The memory-access methods of Unsafe were deprecated for removal by JEP 471 in Java 23, and since JEP 498 in Java 24 the JVM prints a warning on their first use, but allocateInstance() is not one of them. The compiler still warns that Unsafe is an internal API that may be removed, so application code never uses it.
8. Ways to Create an Object Without the new Keyword Compared
The two questions that decide the choice are whether the constructor runs and whether the API is safe to use in application code. The table answers both for Java 25, plus the objects that the language creates for us, such as string literals and autoboxed numbers.
| Way | Runs a constructor | Java 25 status | Typical use |
|---|---|---|---|
| new | Yes | Standard | Application code |
| Constructor.newInstance() | Yes | Standard | Frameworks, plugins, class names from configuration |
| Class.newInstance() | Yes | Deprecated since Java 9 | Old code only, replace it |
| MethodHandles.Lookup.findConstructor() | Yes | Standard | Libraries that create many objects of a runtime class |
| clone() | No | Standard, needs Cloneable | Copies of arrays and Cloneable classes |
| Deserialization | No (yes for records) | Standard, filter untrusted input | Caches, session replication, legacy messaging |
| Factory method, Supplier, builder | Yes, inside | Standard | Application code, readable creation |
| Unsafe.allocateInstance() | No | Internal, not deprecated | Mocking and serialization libraries |
| Literals, autoboxing, array initializers | Not visible | Standard | Strings, wrapper objects, arrays |
String literal = "Dune"; // "Dune", no new in our code
Integer boxed = 42; // 42, Integer.valueOf() runs for us
int[] pages = {120, 240}; // [120, 240]
9. Loading Plugins by Class Name
Say a reporting app lets each customer pick an export format in a configuration file, such as CSV or PDF. The app ships the exporters as classes that implement one interface, and it creates the configured exporter from its class name at startup.
interface Exporter {
String export(List<String> rows);
}
class CsvExporter implements Exporter {
public CsvExporter() {
}
public String export(List<String> rows) {
return String.join(",", rows);
}
}
String className = CsvExporter.class.getName(); // read from the configuration file in a real app
Exporter exporter = Class.forName(className).asSubclass(Exporter.class).getDeclaredConstructor().newInstance();
String csv = exporter.export(List.of("id", "title")); // "id,title"
The asSubclass() call fails with a ClassCastException when the configured class does not implement Exporter, so a wrong class name stops the app at startup instead of in the middle of an export. For plugins packaged as JAR files, java.util.ServiceLoader does the same lookup through a provider file and needs no class names in the configuration.
10. Object Creation FAQs
Interviewers and readers ask about constructors, singletons and abstract classes when this topic comes up.
10.1. Can we create an object without calling its constructor?
Yes. The clone() method, deserialization of a non-record class and Unsafe.allocateInstance() create an object without running its constructor. The other ways call a constructor, either through reflection or inside a factory method.
10.2. Is Class.newInstance() deprecated?
Yes, since Java 9, but it is not marked for removal. Replace clazz.newInstance() with clazz.getDeclaredConstructor().newInstance(), which reports constructor exceptions as InvocationTargetException.
10.3. Can reflection break a singleton?
Yes, for a singleton with a private constructor in our own module, because setAccessible(true) lets us call the constructor a second time. An enum singleton is safe, because reflection refuses to create enum constants.
enum Config { INSTANCE }
10.4. Can we create an object of an abstract class without new?
No. Reflection on an abstract class throws InstantiationException, and clone() or deserialization always produce an object of a concrete class. An anonymous subclass works, but it needs the new keyword.
11. Conclusion
Java creates objects without the new keyword through reflection, method handles, clone(), deserialization, factory methods and the internal Unsafe class. Reflection and method handles still call a constructor, and getDeclaredConstructor().newInstance() replaces the deprecated Class.newInstance().
Only clone(), deserialization and Unsafe.allocateInstance() skip the constructor, which is useful for copies and libraries but bypasses the checks in the constructor. In application code, a factory method or a builder gives the same flexibility without that risk.
12. References
- Constructor.newInstance() (Java SE 25 API)
- Class.newInstance() deprecation note (Java SE 25 API)
- MethodHandles.Lookup.findConstructor() (Java SE 25 API)
- Object.clone() (Java SE 25 API)
- Java Object Serialization Specification, Object Input Classes
- JEP 471, Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal
- JEP 498, Warn upon Use of Memory-Access Methods in sun.misc.Unsafe
Happy Learning !!
How will you make object of parameterized constructor using the newInstance method of Class class.
Scenerio:
class MyClass{
MyClass(String methodType){
System.out.println(“I am calling this constructor using ” + methodType);
}
}
public class ABC{
public static void main(String[] args) {
//In below scenerio where I will pass my constructor’s parameter value
MyClass meth2 = (MyClass) Class. forName(“packagePath.MyClass“).newInstance();
}
}
hi bro,i just want to say thank you for sharing your knowledge.
Your welcome.
What about this scenario???
String str1=new String(“Hello”);
String str2=s1.concat(” World”);
In this case we are not using any of the methods mentioned above right,but a new String object is getting created in String Constant Pool.
Its underlying source code is like this: return new String(buf, true); you can see “new”
tell me more about this .
Hi Lokesh,
How to create object without new if my class is not cantain default constructor ?
Hi Mohan,
There will be certain scenarios
1. Does not have default constructor and having parameterised constructor.
— In this case you will be using any of the ways mentioned above.
2. Does not have any constructor.
— JVM does the work on our behalf, by creating a default one. For this case also you have to use any of the above mentioned except the deserialisation and using ReflectionAPI.
How about when we make the class as static and directly use its instance. Does this also counts under object creation without new keyword. ?
Absolutely yes.
wonderful query….
There are two reflective methods for creating instances of classes: java.lang.reflect.Constructor.newInstance() and Class.newInstance() https://docs.oracle.com/en/java/javase/22/.
So isn’t the first, second and last choice just point to same thing, i.e. getting instance of Class and running newInstance() method on it (of course in different ways). there by point to same thing that is reflection?
Using clone() of java.lang.Object part is wrong because the clone method is protected. You forget to write that we should implement our public instance of clone() in NewClass or super class of NewClass…
Hi Lokesh,
Your every approach use new keyword but you mention in heading,without new keyword
I disagree. Reason is that in few examples, I am using an existing object to create a new one e.g. clone(). Yes, that exiting object was created with new keyword.
final Value v = Value.class.getConstructor(int.class, int.class, double.class).newInstance(_xval1,_xval2,_pval);
Hi Lokesh:
Can you specify under what circumstances it is better to use each approach ??
What would be the disadvantage of using the new keyword in some situation ?
There are no advantages or disadvantages.. they are simply another ways to achieve this. I believe, I outcome is same, means matter a little less, if not at all.
Also, you might know that most frameworks around us in java world use reflection or class loader or object creation, they seldom use new keyword.
with new keyword , you are tightly coupling your code , whereas with the other techniques , you can make object depending on the some condition just by by passing the class name.