Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Introduction

Java is an Object Oriented Programming (OOP) language. This means that Java uses objects, typically organized in classes, to model states and behaviors.

In this tutorial, we’ll take a look at some of the different ways we can create an object.

In most of our examples, we’ll use a very simple Rabbit object:

public class Rabbit {

    String name = "";
        
    public Rabbit() {
    }
    
    // getters/setters 
}

Our Rabbit doesn’t necessarily have a name, although we can set a name if necessary.

Now, let’s create some Rabbit objects!

2. How to Create an Object Using the new Operator

Using the new keyword is probably the most common way to create an object:

Rabbit rabbit = new Rabbit();

In the example above, we assign a new instance of a Rabbit to a variable named rabbit.

The new keyword indicates that we want a new instance of the object. It achieves this by using the constructor class within that object.

Note that an intrinsic default constructor will be used if no constructors are present in the class.

3. How to Create an Object Using the Class.newInstance() Method

As Java is an object-based language, it makes sense to store Java’s key concepts as objects.

An example is the Class object, where all the information about a Java class is stored.

To access the Rabbit class object, we use Class.forName() with the qualified class name (a name that contains the packages that the class is within).

Once we’ve got the corresponding class object for our Rabbit, we’ll call the newInstance() method, which creates a new instance of the Rabbit object:

Rabbit rabbit = (Rabbit) Class
  .forName("com.baeldung.objectcreation.objects.Rabbit")
  .newInstance();

Note that we have to cast the new object instance to a Rabbit.

A slightly different version of this uses the class keyword rather than the Class object, which is more succinct:

Rabbit rabbit = Rabbit.class.newInstance();

Let’s also use the Constructor class to produce a similar alternative:

Rabbit rabbit = Rabbit.class.getConstructor().newInstance();

In all these cases, we’re using the built-in newInstance() methods available to any object.

The newInstance() method relies on a constructor being visible.

For example, if Rabbit only had private constructors, and we tried to use one of the newInstance methods above, we’d see a stack trace for an IllegalAccessException:

java.lang.IllegalAccessException: Class com.baeldung.objectcreation.CreateRabbits can not access 
  a member of class com.baeldung.objectcreation.objects.Rabbit with modifiers "private"
  at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
  at java.lang.Class.newInstance(Class.java:436)

4. How to Create an Object Using the clone() Method

Now let’s look at how to clone an object.

The clone() method takes an object and produces an exact copy of it assigned to the new memory.

However, not all classes can be cloned.

Only classes that implement the interface Clonable can be cloned.

The class must also contain an implementation of the clone() method, so let’s create a class called CloneableRabbit, which is the same as Rabbit but also implements the clone() method:

public Object clone() throws CloneNotSupportedException {
    return super.clone();
}

Then, our code to clone a CloneableRabbit is:

ClonableRabbit clonedRabbit = (ClonableRabbit) originalRabbit.clone();

If we’re considering using the clone() method, we may want to use a Java copy constructor instead.

5. How to Create an Object Using Deserialization

We’ve covered the obvious examples, so let’s start thinking outside the box.

We can create objects through deserialization (reading external data from which we can then create objects).

To demonstrate this, first, we need a serializable class.

We can make our class serializable by duplicating Rabbit and implementing the Serializable interface:

public class SerializableRabbit implements Serializable {
    //class contents
}

Then we’re going to write a Rabbit named Peter out to a file in a test directory:

SerializableRabbit originalRabbit = new SerializableRabbit();
originalRabbit.setName("Peter");

File resourcesFolder = new File("src/test/resources");
resourcesFolder.mkdirs(); //creates the directory in case it doesn't exist
        
File file = new File(resourcesFolder, "rabbit.ser");
        
try (FileOutputStream fileOutputStream = new FileOutputStream(file);
  ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);) {
    objectOutputStream.writeObject(originalRabbit);
}

Finally, we’re going to read it back in again:

try (FileInputStream fis = new FileInputStream(file);
  ObjectInputStream ois = new ObjectInputStream(fis);) {   
    return (SerializableRabbit) ois.readObject();
}

If we inspect the name, we’ll see that this newly created Rabbit object is Peter.

This whole concept is a big topic of its own, called deserialization.

6. Some Other Ways to Create Objects

If we dive a little deeper, it turns out there are many things we can do that intrinsically create objects.

Below are some familiar classes we use often and others we’d never use.

6.1. Functional Interfaces

We’re able to create an object by using functional interfaces:

Supplier<Rabbit> rabbitSupplier = Rabbit::new;
Rabbit rabbit = rabbitSupplier.get();

This code uses the Supplier functional interface to supply a Rabbit object.

We achieve this using the method reference operator, the double colon operator in Rabbit::new.

The double colon operator article contains more examples, like how to deal with having parameters in the constructor.

6.2. Unsafe.AllocateInstance

Let’s quickly mention a method of creating an object we won’t recommend for our code.

The sun.misc.Unsafe class is a low-level class used in core Java classes, which means it isn’t designed to be used in our code.

However, it does contain a method named allocateInstance, which can create objects without calling a constructor.

As Unsafe is not recommended for use outside of the core libraries, we’ve not included an example here.

6.3. Arrays

Another way to create an object in Java is through initializing an array.

The code structure looks similar to previous examples using the new keyword:

Rabbit[] rabbitArray = new Rabbit[10];

However, when running the code, we see it doesn’t explicitly use a constructor method. So, while it appears to use the same code style externally, the internal mechanism behind the scenes is different.

6.4. Enums

Let’s take another quick look at another common object, an enum.

Enums are just a special type of class, and we think about them in an object-oriented way.

So if we have an enum:

public enum RabbitType {
    PET,
    TAME,
    WILD
}

The code will create objects every time we initialize an enum, which differs from the examples above that create objects at runtime.

7. Conclusion

In this article, we’ve seen that we can use keywords, such as new or class, to create an object.

We’ve learned that other actions, such as cloning or deserializing, can create objects.

Also, we’ve seen that Java is ripe with ways to create an object, many of which we’ve probably already been using without ever thinking about it.

As always, full examples for all of the ways that we’ve discussed are available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.