是的,泛型是一个经常出现的话题,现在又来了......
目前,我有这段代码。 处理器
是一个“简单”的通用接口(interface)。
public final class ProcessorChain<IN extends MessageProvider, OUT extends MessageProvider>
implements Processor<IN, OUT>
{
/**
* The resulting processor
*/
private final Processor<IN, OUT> p;
/**
* Start a processing chain with a single processor
*
* @param p the processor
* @param <X> the input type
* @param <Y> the output type
* @return a single element processing chain
*/
public static <X extends MessageProvider, Y extends MessageProvider>
ProcessorChain<X, Y> startWith(final Processor<X, Y> p)
{
return new ProcessorChain<X, Y>(p);
}
/**
* Private constructor
*
* @param p the processor
*/
private ProcessorChain(final Processor<IN, OUT> p)
{
this.p = p;
}
/**
* Add an existing processor to that chain
*
* <p>Note that this returns a <b>new</b> chain.</p>
*
* @param p2 the processor to add
* @param <NEWOUT> the return type for that new processor
* @return a new chain consisting of the previous chain with the new
* processor appended
*/
public <NEWOUT extends MessageProvider> ProcessorChain<IN, NEWOUT>
chainWith(final Processor<OUT, NEWOUT> p2)
{
return new ProcessorChain<IN, NEWOUT>(merge(p, p2));
}
public Processor<IN, OUT> end()
{
return this;
}
@Override
public OUT process(final ProcessingReport report, final IN input)
throws ProcessingException
{
return p.process(report, input);
}
/**
* Merge two processors
*
* @param p1 the first processor
* @param p2 the second processor
* @param <X> the input type of {@code p1}
* @param <Y> the output type of {@code p1} and input type of {@code p2}
* @param <Z> the output type of {@code p2}
* @return a processor resulting of applying {@code p2} to the output of
* {@code p1}
*/
private static <X extends MessageProvider, Y extends MessageProvider, Z extends MessageProvider>
Processor<X, Z> merge(final Processor<X, Y> p1, final Processor<Y, Z> p2)
{
return new Processor<X, Z>()
{
@Override
public Z process(final ProcessingReport report, final X input)
throws ProcessingException
{
return p2.process(report, p1.process(report, input));
}
};
}
}
所以,目前,我可以写:
// p1 does <X, Y>, p2 does <Y, Z>, p3 does <Z, T>
Processor<X, T> p = ProcessingChain.startWith(p1).chainWith(p2).chainWith(p3).end();
而且它有效。事实上,我从来没有对泛型有那么深入的了解。
我希望能够写的是:
Processor<X, T> p = ProcessingChain.start().add(p1).add(p2).add(p3).end();
我一直在努力尝试做到这一点,但失败了。
我希望能够做到这一点的一个原因也是,在未来能够编写:
Processor<X, T> p = ProcessingChain.start().add(p1).stopOnError().etc().etc()
而且我觉得如果我知道如何.start()
,一路上的“实用”处理器就不会成为问题。
那么,该怎么做呢?
最佳答案
裸启动方法无法推断生成的 ProcessorChain 的类型。此外,正如 @PaulBellora 指出的那样,您所描绘的 start() 方法本身不可能是处理器,因为它没有足够的信息。
您可以使用一个单独的类作为 start() 方法的结果,尽管它不能是无参数的。例如:
public class ProcessorChainFactory<M extends MessageProvider> {
public static <X extends MessageProvider> ProcessorChainFactory<X> start() {
return null;
}
public static <X extends MessageProvider> ProcessorChainFactory<X> start(Class<X> clazz) {
return null;
}
public <X extends MessageProvider> ProcessorChain<M, X> add(Processor<M, X> processor) {
// TODO Auto-generated method stub
return null;
}
}
然后可以通过几种方式调用:
Processor<MessageProvider1, Final> processor = ...;
ProcessorChain<MessageProvider1, Final> processor1 = ProcessorChainFactory.<MessageProvider1> start().add(processor);
ProcessorChain<MessageProvider1, Final> processor2 = ProcessorChainFactory.start(MessageProvider1.class).add(processor);
我的感觉是,这不会比当前的 ProcessingChain.startWith(p1)
让您走得更远,但也许会有帮助。
关于java - 另一个对泛型感到困惑的可怜灵魂...如何向此代码添加静态 .start() 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14616172/