If you want to deepen your understanding of Java, read this, so I will read Effective Java while interpreting it in my own way. I am reading the second edition that I was reading. https://www.amazon.co.jp/EFFECTIVE-JAVA-Java-Joshua-Bloch/dp/4621066056/ref=pd_sbs_14_3/355-5139262-7829161?_encoding=UTF8&pd_rd_i=4621066056&pd_rd_r=ac861412-beae-43a8-872a-8b853aa69980&pd_rd_w=oIuWA&pd_rd_wg=nhmjU&pf_rd_p=7642417c-6494-4d06-a2b0-fcb0e0b3c563&pf_rd_r=HAEC02ASTQVJ4SPSM92Q&psc=1&refRID=HAEC02ASTQVJ4SPSM92Q
I'm wondering if there are various things that make me happy if I replace the processing that was implemented using the constructor with a static factory method.
Example 1
public static Boolean valueOf(boolean b){
return b ? Boolean.TRUE : Boolean.FALSE;
}
Example 2
//Service provider framework
public interface Service{
//Service-specific methods here
}
//Service provider interface
public interface Provider{
Service newService();
}
//Non-instantiable class for service registration and access
public class Service{
private Service(){} //Suppress instantiation (item 4)
//Associate service name with service
private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
//Provider registration API
public static void registerDefaultProvider(Provider p){
registerProvider(DEFAULT_PROVIDER_NAME,p);
}
public static void registerProvider(String name,Provider p){
providers.put(name,p);
}
//Service access API
public static Service newInstance(){
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static Service newInstance(String name){
Provider p = providers.get(name);
if (p == null)
throw new IllegalArgumentException(
"Nn provider registered with name:" + name
);
return p.newService();
}
}
-Constructor is the process that is executed when creating an instance of a class.
SampleClass instanceA = new SampleClass();
↑ The description of SampleClass () after new is the call to the constructor.
-How to write the constructor: Make it the same as the class name
public class SampleClass {
//constructor
public SampleClass(){
System.out.println("It's a constructor");
}
}
↑ When new is done with this, "It's a constructor" is output as standard.
-Unlike methods, constructors do not return values (writing return will result in an error)
static -Modifiers for creating instance-independent methods and variables
-A static factory method is just a static method that returns an object. -In Example 1, boolean basic data value (b) is converted to a Boolean object.
-Similar names but different from static factory methods ・ Explanation is omitted here
-An interface is a description of a "variable" or "method type" without writing the specific processing of the method in the class. -The condition is that "all methods are abstract methods" and "basically they do not have any fields". -Since the processing content is not specifically written, it is only necessary to implement the processing content when you want to use it, which is convenient when processing changes may occur in the future (details can be postponed).
-The constructor will be executed without permission when new, but if it is a static factory method, it will be given a nice name, so readability will improve.
For example, suppose there is a process that returns a BigInteger that is a probable prime.
-How to write in the constructor
BigInteger(int, int, Random)
-How to write with static factory method
BigInteger.probablePrime
… Which one is easier to understand?
・ It's natural, but since it's static, it's not instantiated into anything. Must be new to call the constructor ・ It's not so good to create a lot of new objects unnecessarily.
-The constructor does not return a return value, but the static factory method is just a method, so it can be returned, so it is flexible. ・ A service provider framework like Example 2 (hiding the contents and using it as an API) will also be created.
・ Redundant writing can be simplified For example, in the case of a constructor, what I had to write like this
Map<String, List<String>> m =
new HashMap<String, List<String>>();
You can write this as a static factory method
Map<String, List<String>> m = HashMap.newInstance();
It ’s simple, is n’t it?
Of course, behind the scenes, the static factory method is implemented like this
public static <K, V> HashMap<K, V> newInstance() {
return new HashMap<K. V>;
}
-Unlike the constructor, Javadoc does not recognize it well
name | role |
---|---|
valueOf | Returns an instance with the same value as the parameter. It is essentially a type conversion method. |
of | Alternative to valueOf. A more concise one. |
getInstance | Returns the instance specified by the parameter, but does not have the same value. For singletons, getInstance takes no arguments and returns its only instance. |
newInstance | Similar to getInstance, except that the individual instances returned by newInstance are all separate instances. |
getType | Similar to getInstance, but used when the factory method is in a different class than the target class. Type indicates the type of object returned by the factory method. |
newType | Similar to newInstance, but used when the factory method is in a different class than the target class. Type indicates the type of the object returned by the factory method. |
[Read Effective Java] Chapter 2 Item 2 "Consider a builder when faced with a large number of constructor parameters" https://qiita.com/Natsukii/items/eb8fec0d8cae567f6647
Recommended Posts