[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