zoukankan      html  css  js  c++  java
  • 第一条:考虑用静态工厂方法代替构造器

    静态工厂方法的第四大优势在于,他们可以返回原返回类型的任何子类型的对象。

    发行版本1.5中引入的类java.util.EnumSet没有共有构造器,只有静态工厂方法。它们返回两种实现类之一,具体取决于底层枚举类型的大小:如果它的元素小于等于64,就像大多数枚举类型一样,静态工厂方法就会返回一个RegularEnumSet实例,用单个long进行支持;如果枚举类型元素个数大于64个,工厂就返回JumboEnumSet实例,用long数组进行支持。具体的工厂方法代码如下所示:

    View Code
     /**
         * Creates an empty enum set with the specified element type.
         *
         * @param elementType the class object of the element type for this enum
         *     set
         * @throws NullPointerException if <tt>elementType</tt> is null
         */
        public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
            Enum[] universe = getUniverse(elementType);
            if (universe == null)
                throw new ClassCastException(elementType + " not an enum");
    
            if (universe.length <= 64)
                return new RegularEnumSet<E>(elementType, universe);
            else
                return new JumboEnumSet<E>(elementType, universe);
        }

    注意:枚举类型大小是指枚举类型中的元素个数,如下列枚举类型DataBaseType,它的大小为4。

        //现支持的数据库类型枚举类型定义,枚举类型大小为4.
        enum DataBaseType {
            MYSQL, ORACLE, DB2, SQLSERVER
        }

    这里既然提到了EnumSet,那么也可以讲讲EnumMap,下面给出一个EnumMap的实例:

    EnumMapDemo

    View Code
    package edu.sjtu.erplab.collection;
    
    import java.util.EnumMap;
    
    //现支持的数据库类型枚举类型定义
    enum DataBaseType {
        MYSQL, ORACLE, DB2, SQLSERVER
    }
    
    public class EnumMapDemo {
    
        // 类中定义的获取数据库URL的方法以及EnumMap的声明。
        private EnumMap<DataBaseType, String> urls = new EnumMap<DataBaseType, String>(
                DataBaseType.class);
    
        // 构造函数
        public EnumMapDemo() {
            urls.put(DataBaseType.DB2, "jdbc:db2://localhost:5000/sample");
            urls.put(DataBaseType.MYSQL, "jdbc:mysql://localhost/mydb");
            urls.put(DataBaseType.ORACLE, "jdbc:oracle:thin:@localhost:1521:sample");
            urls.put(DataBaseType.SQLSERVER,
                    "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb");
        }
    
        /**
        * 根据不同的数据库类型,返回对应的URL
        * @param type     DataBaseType枚举类型实例
        * @return
        */
        public String getURL(DataBaseType type){
                 return this.urls.get(type);
        }
    
        public static void main(String[] args) {
            EnumMapDemo emd=new EnumMapDemo();
            System.out.println(emd.getURL(DataBaseType.ORACLE));
        }
    }

    静态工厂方法的第四大优势在于,在构建参数化类型实例的时候,他们使代码变得更加简洁。

    在调用参数化类的构造器时,即使类型参数很明显,也必须指明。这通常要求接连两次提供类型参数。比如下述实例中,类型参数<String,List<String>>就声明了两次,而此处明显可以看出前后两处的参数类型是相同的。

    Map<String,List<String>> m1=new HashMap<String,List<String>>();

    但是假如有了静态工厂方法,编译器就可以替你找到类型参数。这被称作类型推导(type inference)。例如,假设MyHashMap提供了下面这样的静态工厂方法:

        //静态工厂方法
        public static <K, V> MyHashMap<K, V> newInstance()
        {
            return new MyHashMap<K, V>();
        }

    那么就可以用下面这句简洁的代码替代上面繁琐的声明:

    Map<String,List<String>> m2=MyHashMap.newInstance();

    不过遗憾的是标准的集合实现如HashMap并没有提供工厂方法,但是可以把这些方法放在我们自己实现的工具类中,比如我们自定义实现的MyHashMap中。

    完整的代码示例:

    MyHashMap

    View Code
    package edu.sjtu.erplab.collection;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class MyHashMap<K, V> extends HashMap<K, V> {
        
        //静态工厂方法
        public static <K, V> MyHashMap<K, V> newInstance()
        {
            return new MyHashMap<K, V>();
        }
        
        public static void main(String[] args)
        {
            List<String> l=new ArrayList<String>();
            l.add("zhangsan");
            l.add("lisi");
            l.add("wangwu");
            System.out.println(l);
            
            Map<String,List<String>> m1=new HashMap<String,List<String>>();
            m1.put("m1", l);
            System.out.println(m1);
            
            Map<String,List<String>> m2=MyHashMap.newInstance();
            m2.put("m2", l);
            System.out.println(m2);
        }
    }

     输出结果:

    [zhangsan, lisi, wangwu]
    {m1=[zhangsan, lisi, wangwu]}
    {m2=[zhangsan, lisi, wangwu]}

  • 相关阅读:
    Python for Infomatics 第14章 数据库和SQL应用四(译)
    展望2017
    bing的简单英文字典工具
    自我安慰
    Python for Infomatics 第14章 数据库和SQL应用三(译)
    Python for Infomatics 第14章 数据库和SQL应用二(译)
    Python for Infomatics 第14章 数据库和SQL应用一(译)
    希望父亲早日恢复
    Python for Infomatics 第13章 网页服务四(译)
    Python for Infomatics 第13章 网页服务三(译)
  • 原文地址:https://www.cnblogs.com/xwdreamer/p/2538078.html
Copyright © 2011-2022 走看看