その年あなたはインタフェースを定義しました

4685 ワード

詳細
その年、あなたはインタフェースを定義しました.
public interface WtfService {
    
    public void process(WtfDto dto);
    
}

拡張性を向上させるために、拡張フィールド、Mapタイプを定義し、ドキュメントで「keyとvalueはStringタイプです」と強調しました.
public class WtfDto  implements Serializable {
    
    //other fields

    private Map extInfo;

    public Map getExtInfo() {
        return extInfo;
    }

    public void setExtInfo(Map extInfo) {
        this.extInfo = extInfo;
    }
    
}

次に、このインタフェースを実装します.

public class WtfServiceImpl implements WtfService {

    public void process(WtfDto dto) {
        Map extInfo = dto.getExtInfo();
        for (Entry 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 extInfo = new HashMap();
        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タイプなのに、どうしてDoubleがあるの?
呼び出し元からDoubleが届くのか?
自分でDoubleを伝えてみましょう.

    @Test
    public void error() {
        WtfService service = new WtfServiceImpl();
        WtfDto dto = new WtfDto();
        Map extInfo = new HashMap();
        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 extInfo = new HashMap();
            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 extInfo;  
//  
//    public Map getExtInfo() {  
//        return extInfo;  
//    }  
//  
//    public void setExtInfo(Map extInfo) {  
//        this.extInfo = extInfo;  
//    }  
      
      
  
    private List extInfoList;  
  
    public List getExtInfoList() {  
        return extInfoList;  
    }  
  
//  Effective java      ,        setExtInfoList       
//    public void setExtInfoList(List extInfoList) {  
//        this.extInfoList = extInfoList;  
//    }  

    public void addExtInfo(String key, String value) {  
        if (extInfoList == null) {
			extInfoList = new ArrayList();
		}
		extInfo.add(new MatchVariable(key, value));
    }  
      
}  

豚チームメイトの猫チームメイトはもう他のタイプのパラメータを伝えることができません.