Java:使用仿制药和地图而无需铸造 / @SuppressWarnings



我现在遇到了这个问题多次,并且总是用一些铸件和@SuppressWarnings注释解决了这一点。

相关接口/抽象类:

public abstract class Data { }
public interface DataOperations {
    boolean isValid();
}
public interface DataOperationsFactory<T extends Data> {
    Class<T> getDataClass();
    DataOperations getOperations(T data);
}

示例实现:

public class DataImpl1 extends Data {
    public String foo;
}
public class DataImpl1Operations implements DataOperations {
    private DataImpl1 data;
    public DataImpl1Operations(DataImpl1 data) {
        this.data = data;
    }
    public boolean isValid() {
        return data.foo != null;
    }
}
public class DataImpl1OperationsFactory extends DataOperationsFactory<DataImpl1> {
    public Class<DataImpl1> getDataClass() {
        return DataImpl1.class;
    }
    DataOperations getOperations(DataImpl1 data) {
        return new DataImpl1Operations(data);
    }
}

使用此模式,我可以决定是否每次都需要创建new DataImpl1Operations。或者可能使用final static NO_OP实现或您有什么。

代码:

现在,我想将所有这些工厂放入Map<Class<T>, DataOperationsFactory<T>>(构造函数)中。然后从中读取(getOps方法)。

public class Test {
    Map<Class<?>, DataOperationsFactory<?>> map;
    public Test(List<DataOperationsFactory<?>> fs) {
        for(DataOperationsFactory<?> f : fs) {
            map.put(f.getDataClass(), f);
        }
    }
    @SuppressWarnings("unchecked")
    public <T extends Data> DataOperations getOps(T data) {
        // --> Here I need to do an unchecked cast <--
        DataOperationsFactory<? super T> f =
                (DataOperationsFactory<? super T>) map.get(data.getClass());
        return f.getOperations(data);
    }
}

有没有任何办法在不受任何铸造的情况下执行此操作?

您可以将捕获类型的私人方法委派,因此可以可靠地施放到正确的数据子类:

Map<Class<?>, DataOperationsFactory<?>> map;
// Unchanged
public Test(List<DataOperationsFactory<?>> fs) {
    for(DataOperationsFactory<?> f : fs) {
        map.put(f.getDataClass(), f);
    }
}
public DataOperations getOps(Data data) {
    DataOperationsFactory<?> f = map.get(data.getClass());
    return getOperations(f, data);
}
private static <T extends Data> DataOperations getOperations(DataOperationsFactory<T> f,
                                                             Data data) {
    return f.getOperations(f.getDataClass().cast(data));
}

相关内容

  • 没有找到相关文章

最新更新