Reputation: 2224
I have multiple classes that all inherit from the same Block
class, and want to instantiate one of them based on a variable value.
Here is what I did for now:
public enum MapCases {
FLOOR (Floor.class), // These are all subclass of my Block class
WALL (Wall.class),
ROCK (Rock.class);
private Class<?> blockType;
MapCases (Class<?> pointing) {
this.block = pointing;
}
public Class<?> getType () {
return this.blockType;
}
};
Then later, I try to instantiate them given some data:
private Block[] blocks; // Array of the mother type
...
blocks = new Block[data.length]; // data is an int array
for (int i = 0; i < data.length; i++) {
int choice = data[i];
Class<?> blockType = MapCases.values()[choice].getType();
blocks[i] = new blockType(); // blockType is of unresolved type
}
But Eclipse shows me an error saying it can't resolve blockType to a type (which seems logical given the fact that java don't know yet the type).
How could I achieve what I am trying to do?
Upvotes: 1
Views: 55
Reputation: 55213
You shouldn't need reflection to do this. Consider this instead:
public enum MapCases {
FLOOR {
@Override
public Block makeBlock() {
return new Floor();
}
},
WALL {
@Override
public Block makeBlock() {
return new Wall();
}
},
ROCK {
@Override
public Block makeBlock() {
return new Rock();
}
};
public abstract Block makeBlock();
}
In this case, the enum itself acts as the factory instead of the Class
token it was holding.
Note that if you did want to stick with the Class
token, it should be typed as Class<? extends Block>
, as Elliott Frisch points out in the comments. Then a call to blockType.getConstructor().newInstance()
, which GGrec's answer demonstrates, will return an instance of Block
.
Upvotes: 3
Reputation: 8960
Use reflection to create a new instance from the class blueprint.
Pattern:
Class.forName(className).getConstructor().newInstance();
Your case:
blocks[i] = blockType.getConstructor().newInstance();
Upvotes: 2