[Effective Java 3rd Edition](https://www.amazon.co.jp/Effective-Java-%E7%AC%AC3%E7%89%88-%E3%], which is a must-have book for intermediate Java users and above. 82% B8% E3% 83% A7% E3% 82% B7% E3% 83% A5% E3% 82% A2% E3% 83% BB% E3% 83% 96% E3% 83% AD% E3% 83% 83% E3% 82% AF-ebook / dp / B07RHX1K53) has a Kindle version, so I will summarize it. "Chapter 1 Introduction" is mainly an explanation of terms, so I will skip it.
Previous: None Next: Effective Java 3rd Edition Chapter 3 Methods Common to All Objects
--The static factory method is something like Boolean.valueOf (boolean b)
.
[Good]Static factory method example
public static Boolean valueOf(boolean b) {
return b ? Boolean.True : Boolean.False
}
--Advantages of static factory method --Unlike a constructor, it has a name. --Since the constructor has no name, it is difficult to judge the function by the parameter. --Unlike constructors, you don't have to create a new object for each call. --Avoid creating duplicate objects unnecessarily. --Unlike the constructor, you can return an object of any subtype of the method's return type. --The class of returned objects is changed for each call depending on the value of the input parameter. --The class of the returned object does not have to exist at the time the class containing its static factory method was written. --Static factory method constraints --You can't create a subclass of a class that doesn't have a public or protected constructor --For example, you cannot create a subclass of any of the utility implementation classes in the collection framework. --You should use composition, not inheritance. --It is difficult for programmers to find static factory methods. --Static factory method naming convention - from - of - valueOf - instance or getInstance - create or newInstance - getType - newType - type
[Good]Builder class example
public class NutritionFacts {
private final int savingSize;
private final int savings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder {
//Mandatory
private final int savingSize;
private final int savings;
//Optional default value
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public Builder(int savingSize, int savings) {
this.savingSize = savingSize;
this.savings = savings;
}
public Builder calories(int val) {
calories = val;
return this;
}
public Builder fat(int val) {
fat = val;
return this;
}
public Builder sodium(int val) {
sodium = val;
return this;
}
public Builder carbohydrate(int val) {
carbohydrate = val;
return this;
}
public NutritionFacts build() {
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder) {
savingSize = builder.savingSize;
savings = builder.savings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
@ Builder
usage exampleExample using lombok
import lombok.Builder;
import lombok.NonNull;
@Builder
public class LombokNutritionFacts {
//Mandatory
@NonNull
private final Integer savingSize;
@NonNull
private final Integer savings;
//Setting the default value
@Builder.Default
private final Integer calories = 0;
@Builder.Default
private final Integer fat = 0;
@Builder.Default
private final Integer sodium = 0;
@Builder.Default
private final Integer carbohydrate = 0;
}
[Good]Singleton class using enum type
//Singleton class using enum type
public enum Elvis {
INSTANCE;
public void leaveTheBilding() {
System.out.println("Hello Elvis!");
}
}
//Call example
public class Main {
public static void main(String[] args){
Elvis elvis = Elvis.INSTANCE;
elvis.leaveTheBilding();
}
}
[Good]
//Utility classes that cannot be instantiated
public class UtilityClass {
//Create a private constructor so that it cannot be instantiated
private UtilityClass() {
throw new AssertionError(); //Throw if called in class
}
//Omitted below
}
[Bad]
//Improper use of static utilities. It lacks flexibility and cannot be tested.
public class SpellCheckerStatic {
private static final Lexicon dictionary = new MyDictionary();
private SpellCheckerStatic() {
}
public static boolean isValid(String word) {
//abridgement
}
public static List<String> suggestions(String type) {
//abridgement
}
}
[Good]
//Dependency injection is flexible and testable
public class SpellChecker {
private final Lexicon dictionary;
public SpellChecker(Lexicon dictionary) {
this.dictionary = Objects.requireNonNull(dictionary);
}
public boolean isValid(String word) {
//abridgement
}
public List<String> suggestions(String type) {
//abridgement
}
}
//This creates unnecessary objects, so
String s = new String("bikini");
//Should do this
String s = "bikini";
--You should use static factory methods rather than constructors. --Choose a basic data type over a boxed basic data type and beware of unintended automatic boxing.
public class RomanNumerals {
private static final Pattern ROMAN = Pattern.compile(
"^(?=.)M*(C[MD]|D?C{0,3})" +
"(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
//[Good example] Improved version that reuses objects
static boolean isRomanNumerial(String s) {
return ROMAN.matcher(s).matches();
}
//[Not good example] Performance is poor when used repeatedly
static boolean isRomanNumerialBad(String s) {
return s.matches("^(?=.)M*(C[MD]|D?C{0,3})" +
"(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}
}
--Set null for references that are no longer in use. --Setting null for object references should be an exception rather than normal. --The best way to get rid of a reference that is no longer in use is to bring the variable that contained the reference out of scope.
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; //■ Remove obsolete references ■
return result;
}
//If you need to make it bigger, double it. Secure at least one capacity.
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
}
--Finalizers are unpredictable, usually dangerous and generally unnecessary. --The finalizer alternative from Java 9 is a cleaner, less dangerous than the finalizer, but still unpredictable, slow, and generally not needed. --Instead of a finalizer or cleaner, implement ʻAutoClosable` and request to call the close method when it is no longer needed. Usually use try-with-resource for close.
as its name suggests.
Recommended Posts