[英]Writing a class in a type-safe way
我想寫一個類型安全的代碼。 這是我嘗試過的:
public interface ResultTronsformer<T>{
public T tranform(T t);
}
public class BigDecimalTransformer implements ResultTRansformer<BigDecimal>{
public BigDecimal transform(BigDecimal t){
return t.setScale(0);
}
}
現在我定義了看起來像的Column接口
public interface Column{
public ResultTransformer<?> getTransformer();
}
並希望在方法中使用它
public class Report{
private Map<Column, Object> columnValuePairs;
public void putIntoACollection(Column c, Object columnsValue){
ResultTransformer<?> rt = c.getTransformer();
columnValuePairs.put(c, rt.transform(o)); //Error: Couldn't convert Object
//to the capture of wildcard
}
}
如何重新設計設計以達到理想的類型安全性? 也許我應該在運行時進行類型檢查(拋出異常)?
您可以考慮使用Column,就像它是某種具有特定類型的容器一樣。 這樣,您可以在Column聲明中引入泛型類型。
public interface Column<T>{
public ResultTransformer<T> getTransformer();
}
然后,您可以更改Report方法,如下所示:
public <T> void putIntoACollection(Column<T> c, T columnsValue){
ResultTransformer<T> rt = c.getTransformer();
columnValuePairs.put(c, rt.transform(columnsValue));
}
您可以更改Column
類並使其參數化:
public interface Column<T> {
public ResultTransformer<T> getTransformer();
}
然后你必須參數化putIntoACollection
方法(不需要參數化Report
):
public class Report {
private Map<Column, Object> columnValuePairs;
public <T> void putIntoACollection(Column<T> c, T columnsValue) {
final ResultTransformer<T> rt = c.getTransformer();
columnValuePairs.put(c, rt.transform(columnsValue));
}
}
這樣,您永遠不需要使用捕獲類型。
以下是如何使用它的示例:
private class BigDecimalColumn implements Column<BigDecimal> {
@Override
public ResultTransformer<BigDecimal> getTransformer() {
return new BigDecimalTransformer();
}
}
public static void main(String[] args) {
final Report report = new Report();
report.putIntoACollection(new BigDecimalColumn(), new BigDecimal("3.14"));
}
獲取轉換器時,需要指定類型,因為編譯器當時不會知道它。
一種可能的解決方案是將類作為參數添加到Column的getTransformer並返回專門的ResultTransformer。
public interface ResultTransformer<T> {
public T transform(T t);
}
public interface Column{
public <T> ResultTransformer<T> getTransformer(Class<T> theClass);
}
public class Report{
private Map<Column, Object> columnValuePairs;
public void putIntoACollection(Column c, Object o){
ResultTransformer<Object> rt = c.getTransformer(Object.class);
columnValuePairs.put(c, rt.transform(o));
}
public interface ResultTransformer<T> {
public T transform(T t);
}
另一種方法是概括接口Column。
我們可以放棄所有的借口,只使用該死的原始類型
ResultTransformer rt = c.getTransformer();
一個更自命不凡的解決方案 -
static <T> T transform (ResultTransformer<T> rt, Object obj)
{
T t = (T)obj; // unchecked cast
return rt.transform(t);
}
public void putIntoACollection(Column c, Object obj){
ResultTransformer<?> rt = c.getTransformer();
columnValuePairs.put(c, transform(rt, obj) );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.