简体   繁体   English

避免在泛型层次结构中强制转换

[英]Avoid cast in a generics hierarchy

I have some difficulty to simplify more the problem. 我有一些困难来简化更多问题。 Sorry if they are too many code here. 对不起,如果他们的代码太多了。 I try to improve the architecture of the code above because I hate warning and cast and I feel something wrong. 我尝试改进上面代码的架构,因为我讨厌警告和演员,我觉得有些不对劲。

Now, the code. 现在,代码。 I have a util class with these two parametrized methods (same signature as OpenJPA's CriteriaBuilder...) 我有一个带有这两个参数化方法的util类(与OpenJPA的CriteriaBuilder相同的签名......)

public class MyUtil {
    public void equal(List<?> l, Object value) {
        // do something (see CriteriaBuilder.equal method)
    }

    public <Y extends Comparable<? super Y>> void greaterThan(List<? extends Y> l, Y value) {
        // do something (see CriteriaBuilder.greaterThan method)
    }
}

Then, I want to be able to abstract them to call it via an interface. 然后,我希望能够抽象它们通过接口调用它。

public interface IOperation<T> {
    // maybe make this method generic ? but how ?
    public abstract void doOp(List<T> l, T value); 
}

public abstract class AbstractOperation<T> implements IOperation<T> {
    protected MyUtil myUtil;
}

public class EqualOp extends AbstractOperation<Object> {
    @Override
    public void doOp(List<Object> path, Object value) {
        myUtil.equal(path, value);
    }
}

public class GreaterThanOp<T extends Comparable<? super T>> extends AbstractOperation<T> {
    @Override
    public void doOp(List<T> path, T value) {
        myUtil.greaterThan(path, value);
    }
}

I create a factory 我创建了一个工厂

public class OperationFactory {
    private static OperationFactory instance;
    public static OperationFactory getInstance() {...}

    public IOperation<?> get(String op) {
        if ("=".equals(op)) {
            return new EqualOp();
        } else if (">".equals(op)) {
            return new GreaterThanOp<Comparable<? super Object>>();
        }
        throw new InvalidParameterException();
    }
}

Then I use it : 然后我用它:

public class Client {
    public void needOp(String op) {
        IOperation<String> operation = (IOperation<String>) OperationFactory.getInstance().get(op); // How to avoid this cast ?
        List<String> l = null;
        operation.doOp(l, "a string");
    }
}

My question is : is it possible to avoid this cast in the Client class ? 我的问题是:是否可以在Client类中避免这种强制转换? How ? 怎么样 ? Is there a way to have a better architecture ? 有没有办法建立更好的架构?

Thanks for reading 谢谢阅读

I'm assuming you can require your type to be Comparable . 我假设你可以要求你的类型是可Comparable

Parameterize EqualOp like GreaterThanOp : GreaterThanOp一样参数化EqualOp

public class EqualOp<T extends Comparable<T>> extends AbstractOperation<T> {
    @Override public void doOp(List<T> path, T value) ...

And define get() like this: 并像这样定义get()

public <T extends Comparable<T>> IOperation<T> get(String op) {
    if ("=".equals(op)) {
        return new EqualOp<T>();
    } else if (">".equals(op)) {
        return new GreaterThanOp<T>();
    }
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM