McLoving
McLoving

Reputation: 191

Java generic factory implementation

The best way to explain what I am trying to do is probably in code.

Public class Product
Public class Vendor<T extends Product>

Now I am trying to create a generic factory that will give you a vendor based on the string input param

   Public Factory {
      public Vendor getInstance(String Type){
          Class cls = Class.forName(Type);
          return new Vendor<cls>();
      }
   }

How would I be able to create this generic Factory?

Upvotes: 0

Views: 223

Answers (2)

T. Claverie
T. Claverie

Reputation: 12246

Well, if you absolutely want to create a Vendor based on a parameter you receive, you should use a Class instead of a String. It's also possible to parametrize your method in order to ensure that you receive a T extends Product type.

public class Main {

    static class Product {}
    static class SubProd extends Product {}
    static class Vendor<T extends Product> {}

    public static <T extends Product> Vendor<T> getInstance(Class<T> clazz) {
        return new Vendor<T>();
    }

    public static void main(String[] args) {
        Vendor<SubProd> v = Main.getInstance(Main.SubProd.class);
        System.out.println(v);
    }
}

As you can see, the class parameter is not used directly, however it is used to enforce the type of the vendor returned. This code compiles and runs without warning, exceptions or cast. While using a String, you'd have to handle all exceptions that can occur and probably make ugly casts here and there.

Generics are very powerful, I believe this little examples shows a little of what can be done with them. However, be aware that sometimes, there are more simple and elegant ways to solve a problem.

Upvotes: 1

forhas
forhas

Reputation: 11991

You can't do that since the compiler uses the generic type information internally during the process of compilation.

You might want to send a generic class type to your factory:

   public class Factory {
      public <PRODUCT extends Product> Vendor<PRODUCT> getInstance(Class<PRODUCT> productClazz){
          return new Vendor<PRODUCT>();
      }
   }

Upvotes: 0

Related Questions