views:

123

answers:

1

I have many html forms referring to many persistence classes.

All the html forms are generated by one single class HTMLForm by passing in the respective HTMLFields instances:

public class HTMLForm<T>{
 HTMLForm(HTMLFields[] f, Class<T> classt){
  this.stupidSunWontAllowTnewInstance = classt;

  // ... whatever GWT jazz ....
 }

 public T getPersistenceHandlerClass(){
   try{
     return (T) stupidSunWontAllowTnewInstance.newInstance();
   }
   catch (InstantiationException e){}
   catch (IllegalAccessException e){}
 }

 Class<T> stupidSunWontAllowTnewInstance;
}

HTMLForm looks at HTMLFields[] array to generate the respective html forms. Therefore, each set of HTMLFields[] array require a different persistence class. The persistence classes are like

PostalAddr, PersonInfo, ItemDescr, Preferences, etc, etc.

Now since I cannot do T.newInstance(), stupidSunWontAllowTnewInstance would be assigned (a silly necessity due to sun's architecture of generics) by the HTMLForm constructor and then getPersistenceHandlerClass is used later to get the appropriate persistence handling class.

Since cloud computing charges by the cpu hour, my question is, which would use less cpu, presuming I have about 25 persistence classes to wade thro. The first one above or the one following?

 public T getPersistenceHandlerClass(){
  if (stupidSunWontAllowTnewInstance == PostalAddress.class)
    return new PostalAddress();
  if (stupidSunWontAllowTnewInstance == PersonInfo.class)
    return new PersonInfo();

  if (stupidSunWontAllowTnewInstance == ....
    ....
    ....

  if (stupidSunWontAllowTnewInstance == etc.class)
    return new etc();
 }

or a Map of factories

 public static Map<PersistenceHandlerFactoryInterface> PHFactories;
 public T getPersistenceHandlerClass(){
  return
   PHFactories.get(stupidSunWontAllowTnewInstance).createInstance();
 }

or make a better suggestion (with cpu consumption consideration) on how I should overcome java generics shortcoming, for another way to instantiate from parameter T. (Or critique me why I'm being too heady criticising sun's generic parametric shortcoming).

+2  A: 

I would go with the first form - I very much doubt that any performance difference is going to be significant. If you're really worried about it though, measure the difference.

Another alternative is to use an enum:

public enum PersistenceHandlerFactory
{
    POSTAL_ADDRESS
    {
        @Override Object newField()
        {
            return new PostalAddress();
        }
    },
    ...;

    public abstract Object newField();
}

Then pass your enum value into the constructor instead of Class<T>. No reflection, no large if/else block, and you don't accidentally end up trying to use it with a class you don't support or a type without a public parameterless constructor. The downside is that you don't have compile-time prevention of:

new HtmlForm<PersonInfo>(PersistenceHandler.POSTAL_ADDRESS)

You could make an execution-time check for that, but it would be somewhat messy.

Overall, I'd still go for the first version unless you have a good reason not to.

Jon Skeet