Effective Java--第1条静态工厂方法代替构造方法

简介: Effective Java--第1条静态工厂方法代替构造方法

640.jpg


为什么要用静态工厂方法代替构造方法???

  1. 静态方法有名称。构造器名和类名一致,静态方法名可以自己定义,例如,BigInteger.probalePrime,可读性强.
  2. 静态方法, 不必每次调用他的时候都新建一个对象。这也是为啥推荐使用Boolean.valueOf(),不推荐new
  3. 静态方法有返回值,可以返回原返回类型任何子类对象,有更大的灵活性。
  4. 使代码变得更加简洁


import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class Services {
    private Services(){
    }
    // Map Service Name to Services 
    public static final Map<String,Provider> providers =  new ConcurrentHashMap<String, Provider>();
    public static final String DEFAULT_PROVIDER_NAME = "<def>";
    // Provider Register API 
    public static void registerDefaultProvider(Provider p){
        registerProvider(DEFAULT_PROVIDER_NAME,p);
    }
    public static void registerProvider(String defaultProviderName, Provider p) {
        providers.put(defaultProviderName, p);
    }
    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("No provider registered with name: " + name);
        }
        return p.newService();
    }
}


静态工厂方法代替构造器去创建对象, 在可读性,不重复new对象,和灵活性,代码更简洁4方面有优势。

测试类:

public class Test {
  /**
   * 静态工厂方法主要缺点,类如果不含公有的或者受保护的构造器,就不能子类话。
   * 静态工厂的第二个缺点在于,他们与其他静态方法实际上没有其他区别。
   * 
   * @param args
   */
    public static void main(String[] args) {
        // Providers would execute these lines
        Services.registerDefaultProvider(DEFAULT_PROVIDER);
        Services.registerProvider("comp", COMP_PROVIDER);
        Services.registerProvider("armed", ARMED_PROVIDER);
        // Clients would execute these lines
        Service s1 = Services.newInstance();
        Service s2 = Services.newInstance("comp");
        Service s3 = Services.newInstance("armed");
        System.out.printf("%s, %s, %s%n", s1, s2, s3);
    }
    private static Provider DEFAULT_PROVIDER = new Provider() {
        public Service newService() {
            return new Service() {
                @Override
                public String toString() {
                    return "Default service";
                }
            };
        }
    };
    private static Provider COMP_PROVIDER = new Provider() {
        public Service newService() {
            return new Service() {
                @Override
                public String toString() {
                    return "Complementary service";
                }
            };
        }
    };
    private static Provider ARMED_PROVIDER = new Provider() {
        public Service newService() {
            return new Service() {
                @Override
                public String toString() {
                    return "Armed service";
                }
            };
        }
    };
}


相关文章
|
6天前
|
Java
java构造方法,构造代码块,静态代码块的执行顺序
本文介绍了Java中构造方法、构造代码块和静态代码块的执行顺序。静态代码块用`static`声明,在JVM加载类时执行一次;构造代码块在每次创建对象时执行,先于构造方法;构造方法用于对象初始化,创建对象时调用。示例代码展示了这三者的输出顺序,并解释了它们的区别和应用场景。
|
1月前
|
安全 Java 程序员
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
57 13
|
4月前
|
Java 程序员 数据库连接
Java执行顺序大揭秘:静态块、非静态块和构造方法谁先谁后?
本文详细介绍了Java中的初始化块,包括静态初始化块和非静态初始化块的概念、执行顺序和实际应用场景。通过具体示例,帮助读者理解这两种初始化块的区别和使用场景,让面试官对你刮目相看。
56 0
Java执行顺序大揭秘:静态块、非静态块和构造方法谁先谁后?
|
4月前
|
Java
在Java中定义一个不做事且没有参数的构造方法的作用
Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。
|
5月前
|
设计模式 Java 测试技术
Java零基础-构造方法详解
【10月更文挑战第5天】Java零基础教学篇,手把手实践教学!
66 1
|
5月前
|
Java
java构造方法时对象初始化,实例化,参数赋值
java构造方法时对象初始化,实例化,参数赋值
142 1
|
6月前
|
Java API
java调用构造方法
java调用构造方法
63 3
|
7月前
|
Java
【Java基础面试十九】、构造方法能不能重写?
这篇文章指出Java中的构造方法不能被重写,因为构造方法必须与类名相同,而重写要求子类方法与父类方法同名,允许构造方法重写将违背这一规则。
【Java基础面试十九】、构造方法能不能重写?
|
5月前
|
Java
java构造方法的两种传值调用对实参的影响
java构造方法的两种传值调用对实参的影响
42 0
|
5月前
|
Java 程序员 编译器
【Java】继承、super、final、子类构造方法
【Java】继承、super、final、子类构造方法
70 0

热门文章

最新文章