DEV Community

Mackenly Jones
Mackenly Jones

Posted on • Originally published at crtv.dev on

Java "new" Keyword and Constructors

Java

The "new" keyword is used to allocate memory and instantiate a reference data type. Primitive data types include byte, short, int, long, float, double, boolean, and char. Reference data types are other data types that point to or reference other memory locations. They can include Arrays, Classes, Interfaces, Strings, Enumerations, and Annotations.

This illustration from CS@ME does a great job explaining what that actually looks like:

Java

When the "new" keyword is used alongside a class' constructor, a new instance of the class called an object is instantiated. This is because of the encapsulation principle of object-oriented programming. This principle states that the internal state of an object should only be modified through its methods, and direct access to or modification of its fields should be avoided. By forcing the use of the new keyword to call constructors, Java ensures that objects are properly initialized before they're used and that their internal state is protected.

A quick overview of constructors

A constructor's purpose is to establish an object's initial state, differentiating it from other standard methods, thanks to certain specific rules.

Diving deeper, it's also worth mentioning that constructors can be overloaded, similar to regular methods. This means we can have multiple constructors in a class, each with a different parameter list and method signature. This enables more flexibility in initializing an object's state.

class Test {
  private int var1;
  private int var2;

  public Test(int var1, int var2) {
    this.var1 = var1;
    this.var2 = var2;
  }

  public Test() {
    this.var1 = 0;
    this.var2 = 0;
  }
}
Enter fullscreen mode Exit fullscreen mode

Using overloading, programmers can create multiple constructors for their classes. This technique, called constructor overloading, allows programmers to design their classes to be more flexible. You typically want to use a constructor to pass in any required parameters when you instantiate a class as an object. Objects should represent things within your program and ideally should accurately represent that thing as soon as you instantiate it. You can then use setters and other methods to change that state as needed as the state of the object needs to change. In an ideal world, throughout the entire lifecycle of your program, any objects and variables in scope should be the best representation of their current value. Having variables and objects with meaningless values could result in other programmers using them when their true values haven't been set. Using parameterized constructors, programmers can pass in meaningful values to describe the object's initial state.

Another important constructor feature is the 'this' keyword. 'This' refers to the current object — the object whose constructor is being called. It can be used to access the class fields or to call other constructors within the same class. A use case is if you have a variable in your constructor called var1, but one of the class instance variables is also called var1. If you use var1, it will point to the constructor's variable, but if you use this.var1, it will point to the instance variable.

class Test {
  private int var1;
  private int var2;

  public Test(int var1, int var2) {
    this.var1 = var1;
    this.var2 = var2;
  }
}
Enter fullscreen mode Exit fullscreen mode

Often you'll want to name your parameters for your constructor the same as the instance variables in the class. Using "this" enables you to do that without conflict.

Another important note is that the Java compiler automatically creates a default constructor if we don't explicitly define any constructor in a class. Most programmers choose to create their own default constructor, though, because rarely do you want to use the default values.

When is "new" not required?

Sometimes you may want to create a class full of static methods. Often if you have several methods that you need to use throughout your project, you may put these methods into a utility class. Since the utility class itself is just a collection of commonly used methods, we can assume three things:

  1. The name of the class is irrelevant, with no semantic meaning. (ex: utils, tools, etc.)
  2. The methods are not related in any way other than being commonly used throughout the app.
  3. No state needs to be stored in instance variables/attributes because the methods aren't related. Therefore, no constructor is required.

Based on those assumptions, we can fill our class with static methods. Static methods are methods that can be called directly without using the new keyword to instantiate an object. Here's an example:

// Usage:
Utils.printer("Hello World!");

// Implementation:
public static void printer(String str) {
  System.out.println(str);
} // end printer
Enter fullscreen mode Exit fullscreen mode

With our utils class, we don't get any of the benefits of storing an object's state because we do not have to create a new object. This saves memory and results in cleaner code. If we needed to store attributes within an object, this option wouldn't work because we need a constructor instantiated using the "new" keyword to create a memory reference to store our state.

In summary, the "new" operator is required to create an object of a reference type and literally means, "Hey Java, create a new place in memory to point to this thing I'm constructing." If you try to call a constructor without the "new" keyword, Java will interpret your constructor as a method, not a constructor, and it will try to call a method named the same as your constructor, which does not exist, resulting in a compilation error.

Top comments (0)