Misconceptions about the new Operator

New is used to create new objects. But it’s used carelessly.

The new operator only exists so we can create new objects, which take up some memory space. Students usually learn this very early and only much later they learn alternatives (see below). So code made by beginners is often full with direct use of constructors.

Some students even use new String("foo"). But there’s no situation where you’d need a new instance of a string that already exists. They probably just use new because that all they know to create objects, not seeing that the argument "foo" already exists.

Misconceptions

This is what many students think because they do not know any alternatives yet:

  • new” is the regular way to create objects.
  • It’s normal to use new Foo() and then let that constructor do all logic needed to create a new instance.
  • Since many basic JRE classes have public constructors (String, HashMap, File) it must be ok to use them.
  • Since most example codes / tutorials use the new operator it must be a good idea to create objects like that.

While it might be ok and easy enough for some basic types to simply have public constructors it has many disadvantages for the classes you define for your project.

Disadvantages

  • Direct use of a concrete class. So there is a strong dependency to both the interface and the implementation, even though you probably do not use the implementation type for anything other than construction.
  • Hard to maintain. What if you want to switch to another implementation? What if you want to use a cache of existing objects? What if you want to use a different constructor of the same implementation?
  • You need to know how to create the object. All parameters have to be given. What if you want to define in some configuration how the objects are to be created?
  • The constructor then often contains code that should not be there. A constructor should only validate and assign values to inner fields (that’s what construction is about). It should not contain any other logic.

How to do it

There are many design patterns to create objects, such as builders. Anything that doesn’t use new is probably better.

Factories

Only factories should create objects. And anything that only exists to create objects is a factory. There are abstract factories and factory methods. You can learn about them in any good book about design patterns.

The great benefit is that a factory doesn’t have to allocate memory. It can, but existing objects can be returned instead. The factory knows what to do, so you don’t need to.

Inversion of Control / Dependency Injection

Factories are nice but sometimes it would be better if you could simply declare that you need an instance of some interface. This way you do not even need to know which factory or service will create the object. You just get it. Many modern frameworks, such as Java EE, support this.

Example

In Java (8+) you can simply have a static factory method in the interface itself. It can just return a new instance of the default implementation. You can later change how construction works.

Look at java.util.List.of and how it creates a List for you. However, it is unmodifiable.

Here’s a generic example:

package com.example.foo;
public interface IFoo {	
	/** Factory method for IFoo, using FooImpl. */	
	public static IFoo of(int number, String name)  {
		if(number<0)
			throw new IllegalArgumentException("number must be positive");
		java.util.Objects.requireNonNull(name);
		return new FooImpl(number, name);
	}
	//...}
// -----------------------------------
package com.example.foo;
class FooImpl implements IFoo {
	private int number;
	private String name;
	FooImpl(int number, String name)  {
		this.number = number;
		this.name = name;
	}
	//...
}

One thought on “Misconceptions about the new Operator”

  1. I was tring out the Preview of Project Valhalla and it looks like we might have to use “new” to create primitive values. It’s weird but I didn’t find any other way to creat a value.

Leave a Reply

Your email address will not be published. Required fields are marked *