malandro
malandro

Reputation: 107

Java call a method before constructor

I have the class Map with a method setMapName which choose from an Enum mapName to set it, inside the constructor there is a rule to name a cell from the array sector either Alien or Human according to the mapName value, i want to test if the name of the cell is indeed Alien or Human but i get null.

public class Map {
    private Name mapName;
    private final Sector [][] sector;
    private int Matrix [][];
    private static final int X=23;
    private static final int Y=14;
    public Map (){
        sector = new Sector[X][Y];
        for (int i=0; i < X; i++){
            for (int j=0; j<Y; j++) {
                sector[i][j] = new Sector (i,j);
            }
        }
        Matrix = new int[23][14];
        if(mapName==Name.FERMI){
            sector[10][8]=new Alien(10,8);
            sector[10][9]=new Human(10,9);
        }
        if(mapName==Name.GALILEI||mapName==Name.GALVANI){
            sector[10][5]=new Alien(10,5);
            sector[10][7]=new Human(10,7);
        }
    }
    public int[][] getMatrix() {
        return Matrix;
    }   
    public void setMatrix(int matrix[][]) {
        Matrix = matrix;
    }
    public Name getMapName() {
        return mapName;
    }
        public void setMapName(Name mapName) {//this is the method i want to use before the constructor
            this.mapName = mapName;
        }
        public Sector[][] getSectors(){
            return sector;
        }
        public void addSectors(){
            Sector.add(sector);
        }
    }

    public enum Name {
    FERMI, GALILEI, GALVANI
    }

    public class MapTest {
        @Test
        public void testMapAlien(){
            Map map = new Map();
            map.setMapName(Name.FERMI);
            assertEquals(Name.Alien, map.getSectors()[10][8].getSectorName());
        }
    }

Upvotes: 0

Views: 174

Answers (2)

Raphael Amoedo
Raphael Amoedo

Reputation: 4455

Your problem is that you do not have a initial mapName. When you call the constructor, the mapName is null. So...

You can do it from two ways:

//Constructor with argument mapName
public Map (Name mapName){
 setMapName(mapName); //or this.mapName = mapName;
 ...
}

Or:

//Give a value to mapName on the constructor without arguments, but I recommend the first one to your case.
public Map (){
 ...
 mapName = value;
 ...
 setMapName(mapName);
}

Upvotes: 0

Amir Afghani
Amir Afghani

Reputation: 38521

Your setMapName is a non-static member function on your Map class (poorly named as it collides with java.util.Map). That means that it can be called on an existing instance of a Map (e.g. a Map that has already been constructed).

Your problem is that you call setMapName after the constructor has been invoked, but your constructor requires a valid Name to work properly! It's a classic chicken and egg problem.

Why don't you just pass in a MapName to the constructor directly?

public Map (Name mapName){
        sector = new Sector[X][Y];
        for (int i=0; i < X; i++){
            for (int j=0; j<Y; j++) {
                sector[i][j] = new Sector (i,j);
            }
        }
        Matrix = new int[23][14];
        if(mapName==Name.FERMI){
            sector[10][8]=new Alien(10,8);
            sector[10][9]=new Human(10,9);
        }
        if(mapName==Name.GALILEI||mapName==Name.GALVANI){
            sector[10][5]=new Alien(10,5);
            sector[10][7]=new Human(10,7);
        }
        ...
}

Upvotes: 1

Related Questions