如何在Java中使用泛型实现工厂模式?

用户名

我有一个通用接口处理程序

public interface Handler<T> {
  void handle(T obj);
}

我可以有此接口的n个实现。假设我目前有以下两种实现。一个处理字符串对象,另一个处理日期

public class StringHandler implements Handler<String> {
  @Override
  public void handle(String str) {
    System.out.println(str);
  }
}

public class DateHandler implements Handler<Date> {
  @Override
  public void handle(Date date) {
    System.out.println(date);
  }
}

我想写一个工厂,它将根据类类型返回处理程序实例。像这样的东西:

class HandlerFactory {
  public <T> Handler<T> getHandler(Class<T> clazz) {
    if (clazz == String.class) return new StringHandler();
    if (clazz == Date.class) return new DateHandler();
  }
}

我在这家工厂遇到以下错误:

类型不匹配:无法从转换StringHandlerHandler<T>

如何解决这个问题?

赫克托

简单的解决方案

您可以将映射保存Class<T> -> Handler<T>到中Map就像是:

Map<Class<T>, Handler<T>> registry = new HashMap<>();

public void registerHandler(Class<T> dataType, Class<? extends Handler> handlerType) {
    registry.put(dataType, handlerType);
}

public <T> Handler<T> getHandler(Class<T> clazz) {
  return registry.get(clazz).newInstance();
}

在某些地方,初始化处理程序(可能在工厂本身中):

factory.registerHandler(String.class, StringHandler.class);
factory.registerHandler(Date.class, DateHandler.class);

在另一个地方,您可以创建和使用它们:

Handler<String> stringhandler = factory.getHandler(String.class);
Handler<Date> dateHandler = factory.getHandler(Date.class);

更多复杂的解决方案

您可以使用反射来“扫描”类,而不是手动注册映射Class<T> -> Handler<T>,而可以使用反射来完成。

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);
}

然后,您像上面一样创建和使用它们:

Handler<String> stringhandler = factory.getHandler(String.class);
Handler<Date> 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!
}

希望能帮助到你!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Java方法中使用泛型

来自分类Dev

如何在泛型参数中使用Java Reflection

来自分类Dev

如何在Java中使用泛型复制数组

来自分类Dev

如何在泛型中实现空对象模式?

来自分类Dev

如何在Java接口中使用泛型的泛型

来自分类Dev

如何在HashMap中使用泛型?

来自分类Dev

如何在Scala中使用泛型

来自分类Dev

如何在Scala中使用泛型

来自分类Dev

如何使用泛型为TForm后代实现Singleton模式?

来自分类Dev

如何在F#中使用类型注释实现泛型

来自分类Dev

在Java中使用泛型和反射实现接口方法

来自分类Dev

如何实现Java泛型

来自分类Dev

Java泛型与工厂

来自分类Dev

Java泛型与工厂

来自分类Dev

如何避免在策略模式中使用Java和泛型进行未经检查的强制转换

来自分类Dev

如何避免在策略模式中使用Java和泛型进行未经检查的强制转换

来自分类Dev

如何在Java中实现泛型方法

来自分类Dev

如何在Java中使用不同的泛型构造函数

来自分类Dev

谁能举例说明如何在Java的InvokeAll()可调用方法中使用泛型?

来自分类Dev

如何在Java中使用不同的泛型构造函数

来自分类Dev

如何在JAVA中的泛型类中使用override方法

来自分类Dev

如何在派生类型中使用泛型方法

来自分类Dev

如何在方法参数中使用泛型类型投影?

来自分类Dev

如何在类中使用Comparable作为泛型参数

来自分类Dev

如何在TypeScript中使用泛型检测类实例

来自分类Dev

如何在Rust的泛型特征中使用动态调度?

来自分类Dev

如何在模块中使用多泛型?

来自分类Dev

如何在Nim中使用默认泛型类型?

来自分类Dev

如何在React.FC中使用泛型