2

I have a super class like this, it has a factory method:

@DiscriminatorColumn(
      name = "etype",
      discriminatorType = DiscriminatorType.STRING
)
public abstract class ChallengeReward {
      public static ChallengeReward createFromFactory(String rewardType){
      ChallengeRewardType type = ChallengeReward.fromString(rewardType);

      ChallengeReward challengeReward = null;
      switch(type){
      case point:
         challengeReward = new PointChallengeReward();
         break;
      case notification:
         challengeReward = new NotificationChallengeReward();
         break;
      case item:
         challengeReward = new ItemChallengeReward();
         break;
      }

      return challengeReward;
   }

   public String getClientId(){
      return "ABCDEF";
   }
}

and subClasses do not have constructors in themselves. So all challenge rewards live in the same table with a discriminator column called "etype".

The problem is now I want to reflectively invoke the method getClientId(), but I can't instantiate ChallengeReward because it's abstract. So I need to instantiate one of its subclasses but I can't do subclass.newInstance().

What are my options here?

EDIT 1: Sorry, my question was not very clear. The problem is I'm writing a generic servlet that will go through all the classes in the package, so reflection is needed. Though that method is in fact static but I don't know how to statically invoke it since I only know the current class at run time.

EDIT 2: It turns out you can call method.invoke(null) to invoke static methods, thank you madth3

user1322614
  • 587
  • 1
  • 4
  • 11
  • 1
    To invoke the factory method you don't need an instance: http://stackoverflow.com/q/2467544/422353 – madth3 Oct 24 '12 at 18:55
  • In general, if you're using reflection, you've overengineered yourself into a corner and need to think about changing your architecture. Can't you make `getClientId` static? – Wug Oct 24 '12 at 19:01

1 Answers1

1

I think you can get the method through using the class name itself and then invoke the method as below:

     String clientId = null;
     Class challengeRewardClass =Class.forName(ChallengeReward.class.getName());
     Method[] methods = challengeRewardClass.getMethods();
     for(Method method: methods){
        if(method.getName().equals("getClientId")){
            clientId = method.invoke(objectoToBeUsedForMethodCall, null);
        }
     }
Yogendra Singh
  • 33,927
  • 6
  • 63
  • 73