那一年你定义了一个接口_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 那一年你定义了一个接口

那一年你定义了一个接口

 2016/5/29 5:31:25  bylijinnan  程序员俱乐部  我要评论(0)
  • 摘要:那一年,你定义了一个接口:publicinterfaceWtfService{publicvoidprocess(WtfDtodto);}为了良好的扩展性,你定义了一个扩展字段,Map<String,String>类型,并且在文档里强调了“key和value都是String类型”:publicclassWtfDtoimplementsSerializable{//otherfieldsprivateMap<String,String>extInfo
  • 标签:一个 那一年 接口
那一年,你定义了一个接口

class="java" name="code">public interface WtfService {
    
    public void process(WtfDto dto);
    
}


为了良好的扩展性,你定义了一个扩展字段,Map<String, String>类型,并且在文档里强调了“key和value都是String类型”:

public class WtfDto  implements Serializable {
    
    //other fields

    private Map<String, String> extInfo;

    public Map<String, String> getExtInfo() {
        return extInfo;
    }

    public void setExtInfo(Map<String, String> extInfo) {
        this.extInfo = extInfo;
    }
    
}



然后实现这个接口:

public class WtfServiceImpl implements WtfService {

    public void process(WtfDto dto) {
        Map<String, String> extInfo = dto.getExtInfo();
        for (Entry<String, String> entry : extInfo.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "=" + value);
        }
    }
}


测试

  
 @Test
    public void normal() {
        WtfService service = new WtfServiceImpl();
        WtfDto dto = new WtfDto();
        Map<String, String> extInfo = new HashMap<String, String>();
        extInfo.put("name", "Kobe");
        dto.setExtInfo(extInfo);
        service.process(dto);
    }


一切正常。世界看起来是那么完美。

直到某一天,你看到这样的一个报错:

java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.String
	at com.sample.WtfServiceImpl.process(WtfServiceImpl.java:40)
	


你百思不得期解:
明明是Map<String, String>类型,怎么会有Double?
难道调用方还能传一个Double过来?

自己传一个Double看看:

    @Test
    public void error() {
        WtfService service = new WtfServiceImpl();
        WtfDto dto = new WtfDto();
        Map<String, Object> extInfo = new HashMap<String, Object>();
        extInfo.put("name", 10.999);
        dto.setExtInfo(extInfo);	//编译不通过
        service.process(dto);
    }
	


编译不通过。

那Double到底是怎么传过来的?

真相是:
    @Test
    public void warning() {

            WtfService service = new WtfServiceImpl();
            WtfDto dto = new WtfDto();
            //Map<String, Object> extInfo = new HashMap<String, Object>();
            Map extInfo = new HashMap();	//eclipse在这一行会有warning提示
            extInfo.put("name", 10.99);
            dto.setExtInfo(extInfo);
            service.process(dto);

    }
}


对于没有代码洁癖直接忽视waring或者压根就不懂得泛型的猪队友,他就那么自然而然的写出了上面的代码。
虽然有warning,但毕竟编译通过了。

于是你的服务就理所当然的报错了。

你体会到这个世界的残酷了。

你应该像王叔叔那样,定义一个key-value的类:

public class MatchVariable implements Serializable {

    private String key;
    
    private String value;
	
	//getter/setter
	
}



然后把接口的参数类改成这样:
public class WtfDto implements Serializable {
    
    //...other fields

//    private Map<String, String> extInfo;
//
//    public Map<String, String> getExtInfo() {
//        return extInfo;
//    }
//
//    public void setExtInfo(Map<String, String> extInfo) {
//        this.extInfo = extInfo;
//    }
    
    

    private List<MatchVariable> extInfoList;

    public List<MatchVariable> getExtInfoList() {
        return extInfoList;
    }

//根据Effective java这本书的建议,你不应该直接提供setExtInfoList这样的方法
    public void setExtInfoList(List<MatchVariable> extInfoList) {
        this.extInfoList = extInfoList;
    }
    
}


猪队友猫队友再也传不了其他类型的参数给你了。


发表评论
用户名: 匿名