Reputation: 2480
Is there a way for me to get a super
implementation directly through getContructor
? I want to call the constructor on "this class or any superclass".
The scenario details are that I have a base class that builds its data using reflection but the data is coming in from an external file. The external loader has a lookup that checks to see if data exists for a particular class and all of that is wrapped into ImplementedCard
, below.
This works fine (enough) and isn't directly related to the question aside from my needing to be able to create all of these instances starting from an ImplementedCard
instance:
public class Card implements DeepCopyable<Card> {
protected ImplementedCardList.ImplementedCard implementedCard;
public Card() {
this.implementedCard = ImplementedCardList.getInstance().getCardForClass(this.getClass());
this.initFromImplementedCard(this.implementedCard);
}
public Card(ImplementedCardList.ImplementedCard implementedCard) {
this.implementedCard = implementedCard;
this.initFromImplementedCard(this.implementedCard);
}
public void initFromImplementedCard(ImplementedCardList.ImplementedCard implementedCard) {
if (implementedCard != null) {
this.name_ = implementedCard.name_;
/* ... and so on */
}
}
// This deepCopy pattern is required because we use the class of each card to recreate it under certain circumstances
@Override
public Card deepCopy() {
Card copy = null;
try {
try {
copy = this.getClass().getConstructor(ImplementedCardList.ImplementedCard.class).newInstance(this.implementedCard);
} catch(NoSuchMethodException e) {
if(!this.getClass().equals(TestHero.class)) {
log.warn(this.getClass().toString() + " is missing ImplementedCard constructor");
}
copy = getClass().newInstance();
} catch(InvocationTargetException e) {
log.error("InvocationTargetException error", e);
copy = getClass().newInstance();
}
} catch(InstantiationException e) {
log.error("instantiation error", e);
} catch(IllegalAccessException e) {
log.error("illegal access error", e);
}
if (copy == null) {
throw new RuntimeException("unable to instantiate card.");
}
copy.name_ = this.name_;
/* ... and so on */
return copy;
}
}
This base class is then extended like so:
public class Minion extends Card implements CardEndTurnInterface, CardStartTurnInterface {
public Minion() {
super();
}
public Minion(ImplementedCardList.ImplementedCard implementedCard) {
super(implementedCard);
}
@Override
public void initFromImplementedCard(ImplementedCardList.ImplementedCard implementedCard) {
if (implementedCard != null) {
super.initFromImplementedCard(implementedCard);
/* custom init goes here */
}
}
/* other class details follow */
}
public abstract class Hero extends Minion implements MinionSummonedInterface {
public Hero() {
super();
}
public Hero(ImplementedCardList.ImplementedCard implementedCard) {
super(implementedCard);
}
/* no custom init; other class details follow */
}
public class Hunter extends Hero {
public Hunter() {
super();
}
public Hunter(ImplementedCardList.ImplementedCard implementedCard) {
super(implementedCard);
}
/* no custom init; other class details follow */
}
This goes on for hundreds of classes. What I want to do is pull out the constructors that do nothing but call super
with the same parameters but when I do, it breaks the getConstructor
call in deepCopy
.
Upvotes: 0
Views: 1943
Reputation: 1585
For each class, you can do:
Hero h = new Hero();
Class hc = h.getClass();
// Get super class and its constructor.
Class<?> sc = hc.getSuperclass();
Constructor scConst = sc.getConstructor(ImplementedCard.class);
// Get super class's parent and its constructor.
Class<?> ssc = sc.getSuperclass();
Constructor sscConst = ssc.getConstructor(ImplementedCard.class);
You could also put this in a loop until you get to Object.class or some other point in the class hierarchy where you'd like to break.
Upvotes: 2
Reputation: 2608
As @nhylated suggested, try
this.getClass().getSuperClass()
Here is a nice explanation regarding why
super.getClass()
behaves like it does.
Upvotes: 1