想让你的java代码更摩登,用列举吧   
               添加时间:2013-6-25 点击量: 
 
                  列举是java 5之后添加的一个首要特点,这个特点不克不及进步机能,然则能让java法度员写出更优雅的代码。
    我之前看到过挺多介绍java列举的不错的帖子,我也来参与以下这个话题。
1. 列举根蒂根基用法
1 /
2   消息的类型,是恳求还是回应
3   @author leo
4  
5  /
6 public enum ReqOrRes {
7     req,res;
8 }
这应当是列举最简单的用法了,即使是如许简单的应用,也能给我们带来便利,
ReqOrRes.req.name() == req  
ReqOrRes.valueOf(req) == ReqOrRes.req  , 经由过程name 和valueOf这两个列举内置的办法,可以便利的将列举在字符串和列举之间转化。
2. 列举中带办法,将处理惩罚逻辑写在列举类中,将调用框架和营业逻辑分别
/
  列举调剂server与slave之间的所有通信报文类型,每个类型的具体描述见com.zdcin.msgbean包,<br>
  每种消息有两个办法供外部调用,按照消息是在哪里产生,对应一方需实现processReq办法,产生消息的一方须要实现processRes办法。
  @author leo
 
 /
public enum MsgType {// MsgType有两个首要办法,processReq,和processRes, 用于完成处理惩罚各类类型的恳求消息和响应消息的逻辑
    / slave获取clientid 
      
     /
    GET_CLIENT_ID {
        @Override
        public void processReq(String json) {// 覆盖父类MsgType中的同名办法,processRes办法在别的一端实现,这个办法的意思是处理惩罚恳求,并发还响应信息
            GET_CLIENT_ID_req req = MsgUtils.getGson().Json(json, GET_CLIENT_ID_req.class);
            GET_CLIENT_ID_res res = new GET_CLIENT_ID_res(req);
            。。。。。
            //用clientid做key找到连接,把消息发还去
            Client.sendMsgToSlave(res.clientId, res);
        }
    },
    / 已经分派过id的slave每次连接到server都要用该号令通知server建树连接 /
    CONNECT {
        @Override
        public void processReq(String json) {
            CONNECT_req req =  MsgUtils.getGson().Json(json, CONNECT_req.class);
            。。。。。
        }
    },
    / 任务指定 /
    TASK_ASSIGN {
        @Override
        public void processRes(String json) {
            //不消实现
        }
    },
/ 心跳 /
    HEART_BEAT {
        
        @Override
        public void processReq(String json) {
            HEART_BEAT_req req = MsgUtils.getGson().Json(json, HEART_BEAT_req.class);
            if (00X.equalsIgnoreCase(req.meta.clientId)) {
                return;
            }
            HEART_BEAT_res res = new HEART_BEAT_res(req);
            Client.sendMsgToSlave(req.meta.clientId, res);
        }
        @Override
        public void processRes(String json) {
            //接管就行,不消处理惩罚
        }
    };
//------------ 到这里,列举类型定义停止了,下边是各个列举都可以用的公共办法
    /
      消息有在调剂server产生的,又在slave上产生的,
      在调剂器上产生的消息,slave须要实现processReq办法,并且slave须要返回res消息给调剂器,调剂器就须要实现processRes办法;
      若是消息是在slave上产生(如主动上报状况的消息),上述流程就反过来。
      @param json
     /
    public void processReq(String json){//父类定义的办法
        throw new RuntimeException(this.name() + .processReq() method not implement.);
    }
    /
      消息有在调剂server产生的,又在slave上产生的,
      在调剂器上产生的消息,slave须要实现processReq办法,并且slave须要返回res消息给调剂器,调剂器就须要实现processRes办法;
      若是消息是在slave上产生(如主动上报状况的消息),上述流程就反过来。
      @param json
     /
    public void processRes(String json){//父类定义的办法
        throw new RuntimeException(this.name() + .processRes() method not implement.);
    }
}
上述列举类的感化是定义消息类型,同时在processReq和processRes办法中实现处理惩罚各类恳乞降响应消息的逻辑,这只是消息一端的代码,一般消息中processReq和processRes只须要呈现一次,在消息的另一段,对称的实现缺乏的那个办法就可以。
这个列举类用起来可能是这个样子的:
public class ReciveWork implements Runnable {
    private String json;
    private Meta meta;
    public ReciveWork(Meta meta, String json) {
        this.meta = meta;
        this.json = json;
    }
    @Override
    public void run() {
        try {
            switch (meta.reqOrRes) {
            case req://按照消息是恳求类型还是响应类型,来决意是调用 processReq办法还是 processRes办法。
                meta.msgType.processReq(json);// meta.msgType 就是MsgType中的CONNECT, GET_CLIENT_ID等列举,这里不断定是哪一个,然则可以断定他们会有processReq办法,如许就可以优雅的动态分发消息给合适的处理惩罚者了 
                break;
            case res:
             // 搜检重发队列,若是在队列中,作废重发
                Client.notifyToStopRetry(meta);
                // 先搜检有对方有没有处理惩罚错误,有的话,直接记录日记,不调用后续的处理惩罚办法了, 相干的错误恢复工作可以在按时任务中进行。
                BaseResMsg baseres = MsgUtils.getGson().Json(json, BaseResMsg.class);
                if (baseres.errCode != 0) {
                    Main.log.error(error in  + baseres.meta.msgType.name() + _res,  [errCode, errMsg]=[
                            + baseres.errCode + ,  + baseres.errMsg + ]);
                } else {
                    meta.msgType.processRes(json);
                }
                
                break;
            }
        } catch (Exception e) {
            Main.log.error(
                    error in  + meta.msgType.name() + .process + meta.reqOrRes.name() + ,  + e.getMessage(), e);
        }
    }
}
worker类实现了Runnable接口,可以放在线程池里,多线程并行分发处理惩罚。
如今看,结果还不错吧,若是不消列举,估计少不了一堆if else分支断定,或者是基于抽象类的模式,每个消息类型写一个子类,去做实现,应当不会比这简单。
3. 带数值可叠加的列举
/
  
  @author leo
 
 /
public enum AppMonitorType {
    /
      读权限
     /
    read(1),
    /
      写权限
     /
    write(2),
    /
      履行权限
     /
    exec(4),
    /
      特别权限
     /
    spic(8);
    
    private int bitValue;
    private AppMonitorType(int v) {//私有的机关办法,只能类初始化时应用,如exec(4),
        this.bitValue = v;
    }
    public int getBitValue() {// 返回列举对应的整形值,如 exec(4) 中的4
        return this.bitValue;
    }
    
    //将数值转换成权限列表, 这个办法是静态的, 直接AppMonitoryType.parseBitValue()
    public static List<AppMonitorType> parseBitValue(int bitValue) {
        if (bitValue <= 0) {
            return null;
        }
        List<AppMonitorType> list = new ArrayList<AppMonitorType>();
        for (AppMonitorType type : AppMonitorType.values()) {
            if ((type.bitValue & bitValue) == type.bitValue) {
                list.add(type);
            }
        }
        return list;
    }
    // 将权限列表转换成数值, 重视这个办法是静态的,用的时辰 直接AppMonitorType.getBitValue()
    public static int getBitValue(List<AppMonitorType> list) {
        int i = 0;
        for (AppMonitorType type : list) {
            i |= type.bitValue;
        }
        return i;
    }
}
因为涉及一些营业信息,我姑且用 read write等庖代了本来的列举, 不过用法是一样的, 这个例子斗劲简单,不管用什么体式格式实现都不会很难,当数据量多一些,逻辑错杂一些的时辰,列举的益处应当会表现的更明显。
     你有关于列举应用的一些奇妙的设法吗,迎接提出来,大师一路进步,我也想进一步去发明。
注:若是您感觉这片文章有价值,想转载,请注明出处,不要做一个抄袭者。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》
                     
                  
     
  
 
    
    
列举是java 5之后添加的一个首要特点,这个特点不克不及进步机能,然则能让java法度员写出更优雅的代码。
我之前看到过挺多介绍java列举的不错的帖子,我也来参与以下这个话题。
1. 列举根蒂根基用法
1 /
2 消息的类型,是恳求还是回应
3 @author leo
4
5 /
6 public enum ReqOrRes {
7 req,res;
8 }
这应当是列举最简单的用法了,即使是如许简单的应用,也能给我们带来便利,
ReqOrRes.req.name() == req
ReqOrRes.valueOf(req) == ReqOrRes.req , 经由过程name 和valueOf这两个列举内置的办法,可以便利的将列举在字符串和列举之间转化。
2. 列举中带办法,将处理惩罚逻辑写在列举类中,将调用框架和营业逻辑分别
/
列举调剂server与slave之间的所有通信报文类型,每个类型的具体描述见com.zdcin.msgbean包,<br>
每种消息有两个办法供外部调用,按照消息是在哪里产生,对应一方需实现processReq办法,产生消息的一方须要实现processRes办法。
@author leo
/
public enum MsgType {// MsgType有两个首要办法,processReq,和processRes, 用于完成处理惩罚各类类型的恳求消息和响应消息的逻辑
/ slave获取clientid
/
GET_CLIENT_ID {
@Override
public void processReq(String json) {// 覆盖父类MsgType中的同名办法,processRes办法在别的一端实现,这个办法的意思是处理惩罚恳求,并发还响应信息
GET_CLIENT_ID_req req = MsgUtils.getGson().Json(json, GET_CLIENT_ID_req.class);
GET_CLIENT_ID_res res = new GET_CLIENT_ID_res(req);
。。。。。
//用clientid做key找到连接,把消息发还去
Client.sendMsgToSlave(res.clientId, res);
}
},
/ 已经分派过id的slave每次连接到server都要用该号令通知server建树连接 /
CONNECT {
@Override
public void processReq(String json) {
CONNECT_req req = MsgUtils.getGson().Json(json, CONNECT_req.class);
。。。。。
}
},
/ 任务指定 /
TASK_ASSIGN {
@Override
public void processRes(String json) {
//不消实现
}
},
/ 心跳 /
HEART_BEAT {
@Override
public void processReq(String json) {
HEART_BEAT_req req = MsgUtils.getGson().Json(json, HEART_BEAT_req.class);
if (00X.equalsIgnoreCase(req.meta.clientId)) {
return;
}
HEART_BEAT_res res = new HEART_BEAT_res(req);
Client.sendMsgToSlave(req.meta.clientId, res);
}
@Override
public void processRes(String json) {
//接管就行,不消处理惩罚
}
};
//------------ 到这里,列举类型定义停止了,下边是各个列举都可以用的公共办法
/
消息有在调剂server产生的,又在slave上产生的,
在调剂器上产生的消息,slave须要实现processReq办法,并且slave须要返回res消息给调剂器,调剂器就须要实现processRes办法;
若是消息是在slave上产生(如主动上报状况的消息),上述流程就反过来。
@param json
/
public void processReq(String json){//父类定义的办法
throw new RuntimeException(this.name() + .processReq() method not implement.);
}
/
消息有在调剂server产生的,又在slave上产生的,
在调剂器上产生的消息,slave须要实现processReq办法,并且slave须要返回res消息给调剂器,调剂器就须要实现processRes办法;
若是消息是在slave上产生(如主动上报状况的消息),上述流程就反过来。
@param json
/
public void processRes(String json){//父类定义的办法
throw new RuntimeException(this.name() + .processRes() method not implement.);
}
}
上述列举类的感化是定义消息类型,同时在processReq和processRes办法中实现处理惩罚各类恳乞降响应消息的逻辑,这只是消息一端的代码,一般消息中processReq和processRes只须要呈现一次,在消息的另一段,对称的实现缺乏的那个办法就可以。
这个列举类用起来可能是这个样子的:
public class ReciveWork implements Runnable {
private String json;
private Meta meta;
public ReciveWork(Meta meta, String json) {
this.meta = meta;
this.json = json;
}
@Override
public void run() {
try {
switch (meta.reqOrRes) {
case req://按照消息是恳求类型还是响应类型,来决意是调用 processReq办法还是 processRes办法。
meta.msgType.processReq(json);// meta.msgType 就是MsgType中的CONNECT, GET_CLIENT_ID等列举,这里不断定是哪一个,然则可以断定他们会有processReq办法,如许就可以优雅的动态分发消息给合适的处理惩罚者了
break;
case res:
// 搜检重发队列,若是在队列中,作废重发
Client.notifyToStopRetry(meta);
// 先搜检有对方有没有处理惩罚错误,有的话,直接记录日记,不调用后续的处理惩罚办法了, 相干的错误恢复工作可以在按时任务中进行。
BaseResMsg baseres = MsgUtils.getGson().Json(json, BaseResMsg.class);
if (baseres.errCode != 0) {
Main.log.error(error in + baseres.meta.msgType.name() + _res, [errCode, errMsg]=[
+ baseres.errCode + , + baseres.errMsg + ]);
} else {
meta.msgType.processRes(json);
}
break;
}
} catch (Exception e) {
Main.log.error(
error in + meta.msgType.name() + .process + meta.reqOrRes.name() + , + e.getMessage(), e);
}
}
}
worker类实现了Runnable接口,可以放在线程池里,多线程并行分发处理惩罚。
如今看,结果还不错吧,若是不消列举,估计少不了一堆if else分支断定,或者是基于抽象类的模式,每个消息类型写一个子类,去做实现,应当不会比这简单。
3. 带数值可叠加的列举
/
@author leo
/
public enum AppMonitorType {
/
读权限
/
read(1),
/
写权限
/
write(2),
/
履行权限
/
exec(4),
/
特别权限
/
spic(8);
private int bitValue;
private AppMonitorType(int v) {//私有的机关办法,只能类初始化时应用,如exec(4),
this.bitValue = v;
}
public int getBitValue() {// 返回列举对应的整形值,如 exec(4) 中的4
return this.bitValue;
}
//将数值转换成权限列表, 这个办法是静态的, 直接AppMonitoryType.parseBitValue()
public static List<AppMonitorType> parseBitValue(int bitValue) {
if (bitValue <= 0) {
return null;
}
List<AppMonitorType> list = new ArrayList<AppMonitorType>();
for (AppMonitorType type : AppMonitorType.values()) {
if ((type.bitValue & bitValue) == type.bitValue) {
list.add(type);
}
}
return list;
}
// 将权限列表转换成数值, 重视这个办法是静态的,用的时辰 直接AppMonitorType.getBitValue()
public static int getBitValue(List<AppMonitorType> list) {
int i = 0;
for (AppMonitorType type : list) {
i |= type.bitValue;
}
return i;
}
}
因为涉及一些营业信息,我姑且用 read write等庖代了本来的列举, 不过用法是一样的, 这个例子斗劲简单,不管用什么体式格式实现都不会很难,当数据量多一些,逻辑错杂一些的时辰,列举的益处应当会表现的更明显。
你有关于列举应用的一些奇妙的设法吗,迎接提出来,大师一路进步,我也想进一步去发明。
注:若是您感觉这片文章有价值,想转载,请注明出处,不要做一个抄袭者。
我俩之间有着强烈的吸引力。短短几个小时后,我俩已经明白:我们的心是一个整体的两半,我俩的心灵是孪生兄妹,是知己。她让我感到更有活力,更完美,更幸福。即使她不在我身边,我依然还是感到幸福,因为她总是以这样或者那样的方式出现在我心头。——恩里克·巴里奥斯《爱的文明》



