0

In my program, I've got the following class hierarchy:

public abstract class Effect
  {
  // ...  
  }

public class Effect1 extends Effect
  {
  public static final NAME = "blah blah 1";
  // ...
  }

public class Effect2 extends Effect
  {
  public static final NAME = "blah blah 2";
  // ...
  }

(many more EffectN classes with quite different implementations). Later on, I've got another family of classes using those EffectN's :

public abstract class EffectList
  {
  protected Effect mEffect;

  // ...
  }

public class EffectList1 extends EffectList
  {
  public static final N = Effect1.NAME;

  public EffectList1
    {
    mEffect = new Effect1();
    }

  // ... 
  }

public class EffectList2 extends EffectList
  {
  public static final N = Effect2.NAME;

  public EffectList2
    {
    mEffect = new Effect2();
    }

  // ...
  }

(many more of those EffectListN classes, one for each EffectN).

Now, while the EffectN's really do have quite different implementations, all the EffectListN's are (nearly) identical - the only difference between them is shown above.

Now, had this been C++, all the EffectListN classes would be easily generated with just 1 template, but AFAIK (being quite new to Java) Java generics cannot do this job, can it?

Any suggestions?

1
  • Is this question relevant? Commented Jan 9, 2015 at 17:48

2 Answers 2

1

Are you trying to create generic way to call constructor? If so this could be done by reflection as long as all implementation would supply the same kind of arguments e.g. default constructor:

class EffectList<EffectType extends Effect> {
  public EffectList(Class<EffectType> clazz) {
    try {
      mEffect = clazz.getConstructor().newInstance();
    } catch (Exception ex) {
      // suppressing Exceptions - in production code you should handle it better
      throw new RuntimeException(ex);
    }
    // ...
  }

  // ...
}

then use it like that:

EffectList<Effect1> effectList1 = new EffectList(Effect1.class);
EffectList<Effect2> effectList2 = new EffectList(Effect2.class);

The static field however cannot be handled such way - best you can do is make it an instance variable and obtain the value via reflection as well:

clazz.getDeclaredField("NAME").get(null); // null is used to obtain static fields

Reason why static field cannot be handled is that there would be only one variable shared among all EffectLists (since underneath its only just one class with just compile-time checks added).

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, your comment helped me realize that the static fields are the essence of the problem here. I ended up changing the architecture in such a way that I no longer need to instantiate large numbers of EffectListN classes, but just one instance of each. That let me get rid of the static fields.
1

I don't know how you would do it with C++, but going off your description, no, Java generics would not be able to handle this.

For one, you have static fields that depend on other static fields defined in the EffectN types. There's nothing in Java which sets a restriction that a type should have a static field. You wouldn't be able to dynamically set

public static final N = SomeEffect.NAME;

Second, because of type erasure, you would not be able to do

public EffectList2
{
    mEffect = new SomeEffect(); // assuming SomeEffect is the type parameter
}

you'd need to pass in a Class instance and use reflection to instantiate this type.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.