CodeQL documentation

Inefficient primitive constructor

ID: java/inefficient-boxed-constructor
Kind: problem
Severity: recommendation
Precision: high
Tags:
   - efficiency
   - maintainability
Query suites:
   - java-security-and-quality.qls

Click to see the query in the CodeQL repository

Primitive values (for example int, float, boolean) all have corresponding reference types known as boxed types (for example Integer, Float, Boolean). These boxed types can be used when an actual object is required. While they all provide constructors that take a primitive value of the appropriate type, it is usually considered bad practice to call those constructors directly.

Each boxed type provides a static valueOf method that takes an argument of the appropriate primitive type and returns an object representing it. The advantage of calling valueOf over calling a constructor is that it allows for some caching of instances. By reusing these cached instances instead of constructing new heap objects all the time, a significant amount of garbage collector effort can be saved.

Recommendation

In almost all circumstances, a call of, for example, Integer.valueOf(42) can be used instead of new Integer(42).

Note that sometimes you can rely on Java’s autoboxing feature, which implicitly calls valueOf. For details, see the example.

Example

The following example shows the three ways of creating a new integer. In the autoboxing example, the zero is autoboxed to an Integer because the constructor Account takes an argument of this type.

public class Account {
	private Integer balance;
	public Account(Integer startingBalance) {
		this.balance = startingBalance;
	}
}

public class BankManager {
	public void openAccount(Customer c) {
		...
		// AVOID: Inefficient primitive constructor
		accounts.add(new Account(new Integer(0)));
		// GOOD: Use 'valueOf'
		accounts.add(new Account(Integer.valueOf(0)));
		// GOOD: Rely on autoboxing
		accounts.add(new Account(0));
	}
}

References