专栏首页cwl_Java3分钟快速阅读-《Effective Java》(四)

3分钟快速阅读-《Effective Java》(四)

31.用实例域代替序数

在枚举类当中添加序数,可以帮助我们对于有特定需求的枚举进行排序

public enum Emsemble {
    SOLO(1),DUTE(2),TRIO(3),QUARTET(4),QUINTET(5),SEXTET(6);

    private final int numberOfMusic;
    Emsemble(int number) {
        numberOfMusic = number;
    }
    public int numberOfMusic(){
        return numberOfMusic;
    }
}

测试用例

    public static void main(String[] args) {
        int i = Emsemble.DUTE.numberOfMusic();
        System.out.println(i);
    }

32.使用EnumSet代替位域

日常开发当中我们总会需要使用到位运算符来表示一个对象具有一种或者多种状态的情况,我们有时会用这样的操作:

public class Text {

    public static final int STYLE_BOLD = 1 << 0 ;
    public static final int STYLE_TIACLC = 1 << 1 ;
    public static final int STYLE_UNDERLINE = 1 << 2 ;
    public static final int STYLE_SIRIKETHROUGH = 1 << 3 ;

    public void applyStyles(int style){
        //TODO
    }
}

使用枚举的操作

public class Text {
    public enum Style{
        STYLE_BOLD,STYLE_TIACLC,STYLE_UNDERLINE,STYLE_SIRIKETHROUGH;
    }
    public void applyStyles(int style){
        //TODO
    }
}

33.用EnumMap代替枚举当中的数组

错误示例

public enum Person {
    JMES,LILI,HEARO,LORSE,MARAY,MICK;
    private static final Person[][] HUMAN = {
            {JMES,LILI,HEARO},
            {LORSE,MARAY,MICK}
    };
}

正确示例

    //使用内部嵌套类
    private enum Human{
        JMES,LILI,HEARO,LORSE,MARAY,MICK;
        private static final Map<Person,Map<Person,Human>> MAP = new EnumMap<Person, Map<Person, Human>>(Person.class);
        static {
            for (Person person : Person.values()) {
                MAP.put(person,new EnumMap<Person, Human>(Person.class));
            }
        }
    }

34.用接口模拟可伸缩的枚举

简单来说,用接口来拓展枚举的功能,代码示例如下

//接口
public interface Operator {
    double apply(double x,double y);
}

//实现类
//在枚举当中每一常量都是它的一个对象,所以当这个字段需要传递什么参数时,都需要对应的构造器用于初始化这个参数,并且添加相对应的字段,用于表示和初始化
public enum Operation implements Operator{
    PLUS("+"){
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    },
    MINUE("-"){
        @Override
        public double apply(double x, double y) {
            return x > y ? x - y : y - x;
        }
    },
    TIMES("*"){
        @Override
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVID("-"){
        @Override
        public double apply(double x, double y) {

            return (x == 0 || y == 0) ? 0 :  x / y;
        }
    };

    private final String symbol;
    Operation(String symbol){
        this.symbol = symbol;
    }

}

35.注解优先于命名模式

本条原文中举例当我们使用单元测试的时候只是使用test作为方法开头来命名,这样不够好,可以使用注解来作为方法区分的方式,个人觉得没必要.开发者根据自己情况而定

36.坚持使用@Override注解

好处就是编译器可以帮你做对应检查,省去一些不必要的麻烦

37.用标记接口定义类型

引用原文:总而言之,如果想要定义一个任何新方法都不会与之关联的类型,标记接口就是最好的选择,否则可以使用注解

38.检查参数的有效性

每个方法都有它对应的业务意义,所以当我们方法接收的参数可能存在不安全情况的时候,都要习惯性的记得对它做非空判断以及不符合当前业务逻辑的参数判断.这样可以帮助我们免除和记录很多非必要的异常

39.必要时进行保护性拷贝

简而言之,只要从客户端得到或者返回客户端的可变组件,类就必须要保护性的拷贝这些组件.要杜绝对象可能会被改变的可能性.代码示例如下\

public final class Period {

    private final Date start;
    private final Date end;

    //在构造器当中加入对于开始时间和结束时间的限制和约束,避免当对象被初始化完成之后,被再次恶意修改了时间
    public Period(Date start, Date end) {
        this.start = new Date(start.getTime());
        this.end = new Date(end.getTime());
        if(start.compareTo(end) > 0){
            throw new IllegalArgumentException(start + "after" + end);
        }
    }
    public Date strat(){
        return new Date(this.start.getTime());
    }
    public Date end(){
        return new Date(this.end.getTime());
    }
}

40.谨慎设计方法签名

  • 40.1 谨慎选择方法的名称,请根据不同公司的命名规则进行命名
  • 40.2 不要过于追求提供便利的方法.不管是接口或者是类,方法过多都会导致测试难度加强,不易于学习
  • 40.3 避免过长的参数列表.最多不要超过4个参数为最佳

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java工具集-数学(圆的计算公式)

    cwl_java
  • 经典笔试题-C++篇

    答:for 循环中的变量i 的类型不应定义为vector::size_type, 因为该类型为无符号数值类型,故循环条件将恒成立,为死循环,应将其类型定义为有...

    cwl_java
  • 速读原著-TCP/IP(SNMP对象标识符)

    对象标识是一种数据类型,它指明一种“授权”命名的对象。“授权”的意思就是这些标识不是随便分配的,它是由一些权威机构进行管理和分配的。 对象标识是一个整数序列,...

    cwl_java
  • Java--动态代理

    代理类MyInvocationHandler 实现(必须实现InvocationHandler接口 ):

    SuperHeroes
  • 1044 拦截导弹 1999年NOIP全国联赛提高组 个人博客:attack.cf

    1044 拦截导弹 1999年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 ...

    attack
  • 国外整理的一套渗透测试资源合集

    无心道人
  • R-CNN,Fast R-CNN,Faster-RCNN快速理解

    检测资源合集http://objectdetection.cn/2018/05/14/awesome-object-detection/

    水球喵子
  • 教育部:35所高校获批AI专业、203所获批数据科学专业

    导读:近日,教育部印发了《教育部关于公布2018年度普通高等学校本科专业备案和审批结果的通知》。

    华章科技
  • pyecharts(二):Python可视化利器

    專 欄 ❈陈键冬,Python中文社区专栏作者 GitHub: https://github.com/chenjiandongx ❈ 恭喜本社区专栏作者陈键冬...

    Python中文社区
  • 2018年9月25日TCP三次握手和四次挥手

    其中,ACK是可能与SYN,FIN等同时使用的,比如SYN和ACK可能同时为1,它表示的就是建立连接之后的响应,如果只是单个的一个SYN,它表示的只是建立连...

    武军超

扫码关注云+社区

领取腾讯云代金券