编写高质量代码:改善Java程序的151个建议-学习笔记(5-8章)

来源:互联网 发布:java中的nio 编辑:程序博客网 时间:2024/06/05 17:15

枚举和注解

83.推荐使用枚举定义常亮

public enum SeaSon {    Sping, Summer, Autumn, Winner;    public static SeaSon getCommonSeason() {        return Sping;    }}        for (SeaSon s : SeaSon.values()) {            Log.i("clp", "s values =" + s);        }        Log.i("clp", "common =" + SeaSon.getCommonSeason());

04-19 10:26:24.608 14196-14196/com.example.demo I/clp: s values =Sping
04-19 10:26:24.608 14196-14196/com.example.demo I/clp: s values =Summer
04-19 10:26:24.608 14196-14196/com.example.demo I/clp: s values =Autumn
04-19 10:26:24.608 14196-14196/com.example.demo I/clp: s values =Winner
04-19 10:26:24.608 14196-14196/com.example.demo I/clp: common =Sping

84.使用构造函数协助描述枚举项

public enum SeaSon {    Sping("春"), Summer("夏"), Autumn("秋"), Winner("冬");    private String desc;    SeaSon(String desc) {        this.desc = desc;    }    public String getDesc() {        return desc;    }    public static SeaSon getCommonSeason() {        return Sping;    }}
        for (SeaSon s : SeaSon.values()) {            Log.i("clp", "s values =" + s.getDesc());        }        Log.i("clp", "common =" + SeaSon.getCommonSeason());

构造函数还可以比这个更复杂,传递对象等。

85.小心switch带来的空值异常

    public void doSwSeaSon(SeaSon seaSon) {        switch (seaSon) {            case Sping:                Log.i("clp", "Sping");                break;            default:                Log.i("clp", "其他类型");                break;        }    }
doSwSeaSon(null);

java.lang.NullPointerException: Attempt to invoke virtual method ‘int com.cp.demo.java.SeaSon.ordinal()’ on a null object reference

case的其实是:SeaSon.Sping.ordinal(),所以要做对象的空值判断。

86.在switch的default代码块中增加AssertionError错误

因为枚举类型和case没有强制关系,如果后续增加了一个,没有case,就会导致switch漏掉这个枚举项。

87.枚举使用valueOf前必须进行校验

否则会抛出异常

        List<String> mList = Arrays.asList("Sping", "sss");        for (int i = 0; i < mList.size(); i++) {            SeaSon sea = SeaSon.valueOf(mList.get(i));            if (sea == null) {                Log.i("clp", "没有此枚举值");            } else {                Log.i("clp", "有值");            }        }

java.lang.IllegalArgumentException: sss is not a constant in com.cp.demo.java.SeaSon

两种方案:
1.捕获异常

        List<String> mList = Arrays.asList("Sping", "sss");        for (int i = 0; i < mList.size(); i++) {            try {                SeaSon sea = SeaSon.valueOf(mList.get(i));                Log.i("clp", "有值");            } catch (IllegalArgumentException e) {                Log.i("clp", "没有此枚举值");            }        }

04-19 11:35:20.148 13538-13538/com.example.demo I/clp: 有值
04-19 11:35:20.148 13538-13538/com.example.demo I/clp: 没有此枚举值

2.拓展枚举类

    public static boolean contains(String name) {        for (SeaSon sen : values()) {            if (sen.name().equals(name)) {                return true;            }        }        return false;    }
        List<String> mList = Arrays.asList("Sping", "sss");        for (int i = 0; i < mList.size(); i++) {            boolean sea = SeaSon.contains(mList.get(i));            if (sea) {                Log.i("clp", "有值");            } else {                Log.i("clp", "没有此枚举值");            }        }

88.用枚举实现工厂方法模式更简洁

1.非静态方法实现。

public interface Car {    public void drive();}public class FortCar implements Car {    @Override    public void drive() {        Log.i("clp", "fort drive");    }}public class BuickCar implements Car {    @Override    public void drive() {        Log.i("clp", "buick drive");    }}public enum CarFactory {    FortCar, BuickCar;    public Car create() {        switch (this) {            case FortCar:                return new FortCar();            case BuickCar:                return new BuickCar();            default:                Log.i("clp", "无效参数");        }        return null;    }}

04-19 11:55:34.988 1940-1940/com.example.demo I/clp: fort drive

2.通过抽象方法生成

public enum CarFactory {    FortCar {        @Override        public Car create() {            return new FortCar();        }    }, BuickCar {        @Override        public Car create() {            return new BuickCar();        }    };    public abstract Car create();}

89.枚举项的数量限制的64个以内

long e = -1L >>> -65;//value=1long e = -1L >>> -1;//value=1long e = -1L >>> 63;//value=1long e = -1L >>> 1;//9223372036854775807long e = -1L >>> 62;//value=3int e = -1 >>> 31;//value=1int e = -1 >>> 1;//2147483647

小于等于64和大于64处理的机制是不一样的。

        Enum[] universe = getUniverse(elementType);        if (universe == null)            throw new ClassCastException(elementType + " not an enum");        if (universe.length <= 64)            return new RegularEnumSet<>(elementType, universe);        else            return new JumboEnumSet<>(elementType, universe);RegularEnumSet:    void addAll() {        if (universe.length != 0)            elements = -1L >>> -universe.length;    }JumboEnumSet:    void addAll() {        for (int i = 0; i < elements.length; i++)            elements[i] = -1;        elements[elements.length - 1] >>>= -universe.length;        size = universe.length;    }

所以内部是以64位拆分进行分组。

90.小心注解继承

91.枚举和注解结合使用威力很大

92.注意@Overrig不同版本的区别

如果是Java1.6版本的程序移植到1.5版本环境中,就需要删除实现接口方法上的@Override注解


泛型和反射

93.Java的泛型是类型擦除的

java的编译期和运行期解读:
http://www.360doc.com/content/14/0218/23/9440338_353675002.shtml

编译期:源码->class文件的过程
运行期:在JVM中运行的过程

    public void initList(List<Integer> mList) {    }    public void initList(List<String> mList) {    }

按照上面这种方式写,报错。
initList(List)’ clashes with ‘initList(List)’; both methods have same erasure

        List<String> mList = new ArrayList<String>();        List<Integer> mIList = new ArrayList<Integer>();        Log.i("clp", "is equals=" + (mList.getClass() == mIList.getClass()));

04-25 15:49:13.356 2760-2760/old.pkg.com.myapplicati I/clp: is equals=true

他们擦除后的类型都是List

Java泛型-类型擦除:
http://blog.csdn.net/caihaijiang/article/details/6403349

94.不能初始化泛型参数和数组

        T t = new T();//报错        T[] mTArray = new T[];//报错        List<T> mList = new ArrayList<T>();//报错

以上3个写法,在AS上面都报错,需要在运行期指定T类型。

95.强制声明泛型的实际类型

“`
List mList = CldCalMiniUtil.asList();//正确
List mList = CldCalMiniUtil.asList();//正确
List mList2 = CldCalMiniUtil.asList(1, 2.2);//报错
List mList2 = CldCalMiniUtil.asList(1, 2.2);//正确–这里使用了强制声明

0 0
原创粉丝点击