yoseph1998
yoseph1998

Reputation: 355

How to make an object that is of the class that is specified in a string?

I have a game that runs on a similar system to games like terraria or minecraft, at least in the aspect of being blocky.

I have constructed it in a way where each block is an Object, and there is a specific class (extends a BlockObject archetype) for each type of block.

I have the game save the blocks in a file like following

I get the name of the instance of the Object i am saving, and store it in a string I start writing the information of the given Object in a string that has the Name of the Class(signifieing what type of block it is Ex. a block that is an object of BlockGrass.java would be stored as BlockGrass). Normally when reading information from a save file I am reading the save file, when it gets to the info of the blocks it first saves the Block type in a local string (BlockGrass in this case), also saves the positions (x cordinate, and y cordinate). Then it would run through a series of if statements like the following

if(blockType.equals("BlockGrass"))
{
blocksArray.add(new BlockGrass(...));
}
else if(blockType.equals("BlockStone"))
{
blocksArray.add(new BlockStone(...));
}
etc

now I want to make my game vary dynamic, and want it so that if someone decides to make a new Block class (Modding the game) they do not have to modifiey the MapReader class. so instead of running through a series of if statements as shown above (where everytime a new block class is created, a new if statement must be placed for that block), i want it so that it make a new object of a class that has the same name as the BlockType. to give you a better idea look at the following

BlocksArray.add(new blockType(...));

the reason what is shown above does not work is because blockType is a string that holds the name of the class i want to use. not a Class Name

How could i do something like that?, without using if-statements.

Upvotes: 3

Views: 105

Answers (2)

alainlompo
alainlompo

Reputation: 4434

What you are trying to do is to take advantage of polymorphic behaviours from your BlockObject hierarchy. Therefore using class.forName is the good approach. Once you have invoked newInstance()on the Class variable you will need to cast it to the base class (the archetype as you called it) of your hierarchy of BlockObject class. We have guarantee that since the real class is extending BlockObject, it is a BlockObject according to the definition of inheritance.

Here is an example

public class GameLoader {

    private List<BlockObject> blocksArray = new ArrayList<BlockObject>();

    public Object getNewBlock(String blockClassName) throws     ClassNotFoundException, InstantiationException, IllegalAccessException {

        Class blockClass = Class.forName(blockClassName);
        return blockClass.newInstance();

    }

    public void addNewBlockType(String typeName) throws     ClassNotFoundException, InstantiationException, IllegalAccessException {

        BlockObject castedType = (BlockObject)getNewBlock(typeName); 
        blocksArray.add(castedType);
    }
}

Any method of the base class invoked on such object will display polymorphic behaviours.

Upvotes: 1

redge
redge

Reputation: 1192

This is not compiled and checked but it is just to indicate what must be done.

// first get the class
Class<?> rawclass = Class.forName(String);
// then check an object will fit where you want it.
if (BlockObject.class.isAssignableFrom(rawclass)){
      // create the object, cast it to the correct type and add it
      BlockObject object = (BlockObject) rawclass.newInstance();
      blockArray.add(object);
}

There will be some exceptions to catch out of the forName and newInstance methods.

Upvotes: 0

Related Questions