我有一个通用接口处理程序
public interface Handler{ void handle(T obj); }
我可以有这个接口的n个实现.假设我现在有以下2个实现.一个处理String对象,另一个处理Date
public class StringHandler implements Handler{ @Override public void handle(String str) { System.out.println(str); } } public class DateHandler implements Handler { @Override public void handle(Date date) { System.out.println(date); } }
我想编写一个工厂,它将根据类类型返回处理程序实例.像这样的东西:
class HandlerFactory { publicHandler getHandler(Class clazz) { if (clazz == String.class) return new StringHandler(); if (clazz == Date.class) return new DateHandler(); } }
我在这个工厂得到以下错误:
类型不匹配:无法转换
StringHandler
为Handler
如何解决这个问题?
简单的解决方案
你可以节省您的映射Class
中Map
.就像是:
Map, Handler > registry = new HashMap<>(); public void registerHandler(Class dataType, Class extends Handler> handlerType) { registry.put(dataType, handlerType); } public Handler getHandler(Class clazz) { return registry.get(clazz).newInstance(); }
在某些地方,初始化处理程序(可能在工厂本身):
factory.registerHandler(String.class, StringHandler.class); factory.registerHandler(Date.class, DateHandler.class);
在另一个地方,您创建并使用它们:
Handlerstringhandler = factory.getHandler(String.class); Handler dateHandler = factory.getHandler(Date.class);
更复杂的解决方案
您可以使用反射"扫描"类,而不是手动注册映射Class
,使用反射进行操作.
for (Class extends Handler> handlerType : getHandlerClasses()) { Type[] implementedInterfaces = handlerType.getGenericInterfaces(); ParameterizedType eventHandlerInterface = (ParameterizedType) implementedInterfaces[0]; Type[] types = eventHandlerInterface.getActualTypeArguments(); Class dataType = (Class) types[0]; // <--String or Date, in your case factory.registerHandler(dataType, handlerType); }
然后,您可以像上面一样创建和使用它们:
Handlerstringhandler = factory.getHandler(String.class); Handler dateHandler = factory.getHandler(Date.class);
要实现getHandlerClasses()
,请查看此内容以扫描您的所有类jar
.对于每个班级,您必须检查它是否是Handler
:
if (Handler.class.isAssignableFrom(scanningClazz) //implements Handler && scanningClazz.getName() != Handler.class.getName()) //it is not Handler.class itself { //is a handler! }
希望能帮助到你!