一年前一直是做C++游戏服务器的开发工作,后来被接手了一个java的服务器,也就开始写java了,本来就没有什么基础,就赶紧买来了基本java的编程书,《java 编程思想》,《Effective java》等等。在Effective java中有一条就是"返回0长度的数组,而不是null"。那么我们就借助一段代码来谈谈这一条。
我们将这一条扩展一下,就是返回0长度的容器,而不是null;
我们还可以再扩展一下,就是传递0长度的容器,而不是null;
这个容器可以是java中的List或者Map;
我们看下下面的代码:
@Overridepublic int useSkill(BattleInfos msg, IFighter attacker, Listdefender, Object[] params){ if(defender == null || params == null) { return -1; } for(IFighter defend : defender) { //TODO } return 0;}
如果我们传递0长度的容器,而不是null;则代码可以:
@Overridepublic int useSkill(BattleInfos msg, IFighter attacker, Listdefender, Object[] params){ for(IFighter defend : defender) { //TODO } return 0;}
对于返回长度为0的容器,在这里还是列举一下书中给出的例子:
public class Shop{ private List cheeseInStock = ...; public Cheese[] getCheeses() { if(this.cheeseInStock.size() == 0) { return null; } }}Cheese[] cheeses= shop.getCheeses();if(cheeses == null){ return -1;}//todo
如果我们在原则下面编程,则红色标注的代码则可以省略掉。
那么这个原则适用于C++吗?我们看下我之前犯过的一个错误。
int SectBattle::notify_to_battlers(const int recogn, ACE_Message_Block *mb ){ GameMonitor::PlayerSceneMap *player_scene_map = NULL; player_scene_map = GAMEMONITOR_INSTANCE->find_player_scene_map(this->field_detail_.__field_index , this->field_detail_.__scene_id); if(player_scene_map == NULL) { return -1; } { ACE_READ_GUARD_RETURN(RW_MUTEX, mon, player_scene_map->mutex(), -1); for (GameMonitor::PlayerSceneMap::iterator mov_iter = player_scene_map->begin(); mov_iter != player_scene_map->end(); ++mov_iter) { mov_iter->int_id_->respond_finer_result(recogn,mb); } } return 0;}
if语句,就是防止 player_scene_map为null,引起宕机。但是C++可以返回长度为0的容器吗?
我们看下find_player_scene_map函数的定义:
PlayerSceneMap* GameMonitor::find_player_scene_map(const int tick_id, const int scene_id){ PlayerSceneMap* playerMap = this->player_site_map_.find_object_map(tick_id, scene_id); if(playerMap == NULL) { playerMap = new PlayerSceneMap(); } return playerMap;}
如果为NULL的时候,返回长度为0的PlayerSceneMap,这样子这段内存由谁来维护变成为一个很大的问题。
在这方面java的内存管理确实有优势。如果是C++的话,除了小心编程之外,不知道还有没有更好的办法!