以类型安全的方式编写类

use*_*882 5 java generics

我想写一个类型安全的代码.这是我尝试过的:

public interface ResultTronsformer<T>{
    public T tranform(T t);
}

public class BigDecimalTransformer implements ResultTRansformer<BigDecimal>{

    public BigDecimal transform(BigDecimal t){
        return t.setScale(0);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我定义了看起来像的Column接口

public interface Column{
    public ResultTransformer<?> getTransformer();
}
Run Code Online (Sandbox Code Playgroud)

并希望在方法中使用它

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
    }
}
Run Code Online (Sandbox Code Playgroud)

如何重新设计设计以达到理想的类型安全性?也许我应该在运行时进行类型检查(抛出异常)?

Rap*_*aël 1

您可以更改Column类并使其参数化:

public interface Column<T> {
    public ResultTransformer<T> getTransformer();
}
Run Code Online (Sandbox Code Playgroud)

然后你必须参数化该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));
    }
}
Run Code Online (Sandbox Code Playgroud)

这样,您就不需要使用捕获类型。

以下是如何使用它的示例:

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"));
}
Run Code Online (Sandbox Code Playgroud)