As the title says. Inadvertently creating objects leads to poor performance. Let's devise a little and write it so as not to generate useless objects.
In Java, there are two types: primitive type (basic type) and reference type. Primitive types, such as ints, cannot be placed in a collection. Primitive values must be "boxed" into the appropriate wrapper class (Integer for int), as the collection can only hold object references. When you retrieve an object from the collection, you get the stored Integer. If you need an int, you need to "unbox" it from an Integer using the intValue method. Explicit implementation of this is a source of complexity, so Java has automatic boxing and unboxing features. Automatic boxing for automatic conversion of primitive type to wrapper class Automatic conversion from wrapper class to primitive type is called unboxing.
Primitive type | Wrapper class |
---|---|
boolean | Boolean |
char | Character |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
An object whose state cannot be changed after it is created.
This code will create a new String instance each time this part is executed.
Example 1
String s = new String("stringette"); //Don't do this
This is OK
Example 2
String s = "stringette";
Consider, for example, the Person class with the isBabyBoomer method that determines if a person is a baby boomer. In the way of writing ↓, every time the isBabyBoomer method is called, a new Calender instance, TimeZone instance, boomStart, and boomEnd Date instance are created unnecessarily. Don't do this.
Example 3
public class Person {
private final Date birthDate;
//Omit other fields, methods and constructors
//Don't do this!
public boolean isBabyBoomer() {
//Unnecessary generation of costly objects
Calender gmtCal =
Calender.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calender.JANUARY, 1, 0, 0, 0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965, Calender.JANUARY, 1, 0, 0, 0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0 ;
}
}
Example 4 improved the bad points of Example 3. When the class is initialized, the Calender instance, TimeZone instance, BoomStart, and BoomEnd Date instances are created only once. This can be a significant performance boost if the isBabyBoomer method is called frequently.
Example 4
public class Person {
private final Date birthDate;
//Omit other fields, methods and constructors
/**
*Baby boom start and end dates.
*/
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calender gmtCal =
Calender.getInstance(TimeZone.getTimeZone("GMT");
gmtCal.set(1946, Calender.JANUARY, 1, 0, 0, 0);
BoomStart = gmtCal.getTime();
gmtCal.set(1965, Calender.JANUARY, 1, 0, 0, 0);
BoomEnd = gmtCal.getTime();
}
public boolean osBabyBoomer() {
return birthDate.compareTo(BoomStart) >= 0 &&
birthDate.compareTo(BoomEnd) < 0 ;
}
}
Example 5 is quite slow due to a one-letter typo. The variable sum is declared as Long instead of long. As a result, the program creates about 2 ^ 31 unnecessary Long instances. (Every time you add long i to Long sum, one instance increases)
Lesson: Choose a basic data type over a boxed basic data type and beware of unintended automatic boxing
Example 5
//A terrifyingly slow program! Can you point out the object creation?
public static void main(String[] args) {
Long sum = OL;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
}
[Read Effective Java] Chapter 2 Item 6 "Remove obsolete object references" https://qiita.com/Natsukii/items/5f2edd6a9bcdb94b03e5
Recommended Posts