java参数化通用静态工厂

在Java中是否可以创建一个静态工厂方法/类,它使用接口作为参数化类型并返回给定接口的实现类?

虽然我对generics的了解有限,但这就是我想要做的:

// define a base interface: public interface Tool { // nothing here, just the interface. } // define a parser tool: public interface Parser extends Tool { public ParseObject parse(InputStream is); } // define a converter tool: public interface Converter extends Tool { public ConvertObject convert(InputStream is, OutputStream os); } // define a factory class public class ToolFactory { public static  getInstance( tool) { // what I want this method to return is: // - ParserImpl class, or // - ConverterImpl class // according to the specified interface. if (tool instanceof Parser) { return new ParserImpl(); } if (tool instanceof Converter) { return new ConverterImpl(); } } } 

我想限制客户端代码只将接口’type’插入到我指定的Tool接口扩展的getInstance()方法中。 这样我就确定所插入的工具类型是合法的工具。

客户端代码应如下所示:

 public class App { public void main(String[] args) { Parser parser = null; Converter converter = null; // ask for a parser implementation (without knowing the implementing class) parser = ToolFactory.getInstance(parser); // ask for a converter implementation converter = ToolFactory.getInstance(converter); parser.parse(...); converter.convert(... , ...); } } 

工厂应该在工厂询问之前定义界面的类型(如果它为空,则不小心)。 我知道这不会像我写的那样工作,但我希望其中一位读者知道我想要完成的事情。

getInstance方法的返回类型与传入参数相同,因此当传递Parser接口时,它还返回一个Parser p = new ParserImpl(); 返回p;

在此先感谢帮助我。

有几件事:

  1. 您的工厂几乎肯定会使用来实例化,而不是Tool 对象 。 有人创建一个Parser来传递给你的方法以获得一个Parser有点鸡蛋和鸡蛋。
  2. 我不知道你是否允许使用通配符方法的通用参数; 我认为不会,因为这将是荒谬和毫无意义的。 在参数化方法时,需要为generics参数指定一个名称,以便稍后可以引用它。

将这些放在一起,您的工厂方法可能看起来更像这样:

 public static  T getInstance(Class toolClass) { if (Parser.class.isAssignableFrom(toolClass) { return new ParserImpl(); } else if (Converter.class.isAssignableFrom(toolClass) { return new ConverterImpl(); } // You'll always need to have a catch-all case else the compiler will complain throw new IllegalArgumentException("Unknown class: " + toolClass.getName()); } 

如果要将toolClass的类型限制为接口,则不能在编译时执行此操作,但您当然可以引入运行时检查toolClass.isInterface()

顺便说一句,这种静态硬编码切换通常不是很好 。 在我看来,将类到构造函数关系放在Map并动态查找构造过程会更好。 甚至可以将值存储为Callable Callable并添加一个受保护的方法,允许其他类注册映射。

这并不是说你当前的版本不能正常工作,只是因为它不能很好地扩展,而且现在我认为没有多少工作可以certificate拥有一个单独的工厂而不是调用者只需调用toolClass.newInstance()他们自己。