java parameterized generic static factory

前端 未结 1 957
广开言路
广开言路 2020-12-20 05:24

Is it possible in Java to create a static factory method/class that uses an interface as the parameterized type and return an implementing class of this given interface?

1条回答
  •  有刺的猬
    2020-12-20 06:09

    A couple of things:

    1. Your factory should almost certainly take a class to instantiate, rather than a Tool object. Having someone create a Parser to pass into your method in order to get a Parser is a bit chicken-and-egg.
    2. I don't know if you're allowed to have generic parameters for methods that are wildcards; I presume not since this would be nonsensical and pointless. When you parameterise a method, you need to give the generic parameter a name so that you can refer to it later on.

    Putting these together, your factory method might look more like this:

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

    If you want to restrict the type of toolClass to be an interface, you can't do this at compile-time, but you can of course introduce a runtime check toolClass.isInterface().

    By the way, this static hardcoded switching isn't very nice in general. To my mind, it would be nicer to put the class-to-constructor relationship in a Map and look up the construction process dynamically. Maybe even store the value as a Callable and add a protected method allowing other classes to register mappings.

    That's not to say that your current version doesn't work, just that it doesn't scale very well, and right now I don't think it's doing much to justify having a separate factory rather than the caller simply invoking toolClass.newInstance() themselves.

    0 讨论(0)
提交回复
热议问题