我正在试图弄清楚如何使用Java的泛型来构建一个程序,并想知道我是在做一些根本错误的事情,或者只是在我的代码中遗漏了一个简单的错误。
说我有一个通用类:
public interface Handler<T>{
public void process(T t);
}
另一个泛型类将Handler作为泛型参数(伪代码):
public interface Processor<S extends Handler<T>>{ //<== Error: cannot find symbol 'T'
public void addHandler(S u);
public void process(T t);
}
提供样板实现的抽象实现
public abstract class ProcessorImpl<.....> implements Processor<.....>{
...
}
将处理器视为一个对象,将处理数据的请求分派给任意数量的处理程序。具体实例可以是流程管道,拦截过滤器,事件系统等的变体。
我希望能够像以下一样使用它:
Handler<String> myHandler1 = new HandlerImpl<String>();
Handler<String> myHandler2 = new HandlerImpl<String>();
Handler<Integer> myHandler3 = new HandlerImpl<Integer>();
Processor<Handler<String>> proc = ProcessorImpl<Handler<String>>();
proc.addHandler(myHandler1);
proc.addhandler(myHandler2);
proc.addhandler(myHandler3);//this should be an error!
我无法让它发挥作用。在纸面上看起来它应该是微不足道的,任何想法?
由于
答案 0 :(得分:4)
因此每个类型参数仅在类中定义,因此在T
类中未定义或提供Processor
。
您可能希望Processor
成为:
public interface Processor<T>{
public void addHandler(Handler<? super T> u);
public void process(T t);
}
此处您声明的Processor
只能处理特定类型的事件/输入,例如String
,Integer
等。以下声明有效:
Processor<String> proc = ...
proc.addHandler(new Handler<String>()); // valid
proc.addHandler(new Handler<Object>()); // valid, as Strings are Objects too
proc.addHandler(new Handler<Integer>()); // invalid, not a String handler
proc.process("good"); // valid
proc.process(1); // invalid, not a String
如果Processor
旨在在运行时处理类型并根据适当的运行时类型进行动态调度,则可以将proc
(在上一个示例中)声明为Processor<?>
。然后所有的陈述都是有效的。
答案 1 :(得分:1)
这些更改应该有效:
public interface Processor<T, S extends Handler<T>>
和
class ProcessorImpl<T, S extends Handler<T>>
implements Processor<T, S>
和
Processor<String, Handler<String>> proc = new ProcessorImpl<String, Handler<String>>();
答案 2 :(得分:0)
它不应该工作,因为你的T = String和整数的处理程序是不允许的。 在编译时,您的类将具有方法进程(String t)而不是process(Integer t)。