marcos guerra marcos guerra - 6 months ago 7
Java Question

Java Not Using a Static Variable

I have the method

drawPoliticCard()
that i need to use in the method from another class
applyBonus()
, i can do it easily using a static attribute but the problem is that i should be able to run two instances of the game independently at the same time, so if use static both instances will be sharing the same deck of cards. That's why i wanted to know if there is a way to do it without using a static attribute. I'll omit the getters and setters of the attributes to make it more concise.

public class PoliticCard {
private static ArrayList<Color> politicCards;

public void setDeck(){
setPoliticCards(new ArrayList<Color>());
getPoliticCards().add(Color.BLACK);
getPoliticCards().add(Color.PURPLE);
getPoliticCards().add(Color.BLUE);
}
public static void drawPoliticCard(Player player){
player.getPoliticCards().add(getPoliticCards().get(0));
getPoliticCards().remove(0);
}
}





public class Bonus {
protected int number;//The number of politic cards added in BonusPoliticCard
}





public class BonusPoliticCard extends Bonus {
public BonusPoliticCard(int number) {
this.number=number;
}
public void applyBonus(Player player){
int i=0;
while(i<number){
PoliticCard.drawPoliticCard(player);
i++;
}
}

}


I know that to call a method from another function you should create a new instance of the class, but if i do i get an
nullpointerexception
when testing.

public class BonusPoliticCard extends Bonus {
public BonusPoliticCard(int number) {
this.number=number;
}
public void applyBonus(Player player){
int i=0;
while(i<number){
PoliticCard politicCard = new PoliticCard();
politicCard.drawPoliticCard(player);
i++;
}
}

}

public class BonusPoliticCardTest {

@Test
public void testBonusPoliticCard() {//This ran fine when it was static
Bonus bonus = new BonusPoliticCard(3);
Player player = new Player(1);
PoliticCard politicCard = new PoliticCard();
politicCard.setDeck();
bonus.applyBonus(player);
assertNotNull(player.getPoliticCards().get(2));

}

}

Answer

Since Player class is not shown in the problem, there are two cases where NullPointerException can be thrown:

(1) PoliticCard instance created in BonusPoliticCardTest is different from the instance you create in BonusPoliticCard class. So the politicCards arrayList that you set via politicCard.setDeck() inside BonusPoliticCardTest is never going to be available with PoliticCard instance you create inside BonusPoliticCard class. Also note that the politicCards arrayList of PoliticCard instance is both created and set inside setDeck(). So, during the call to bonus.applyBonus(player); the politicCards arrayList reference points to null, hence NullPointerException will be thrown at following line for getPoliticCards().get(0):

player.getPoliticCards().add(getPoliticCards().get(0)); // inside drawPoliticCard(Player player) method

(2) Player class should have ArrayList politicCards created inside its constructor otherwise we would get NullPointerException on the following line for player.getPoliticCards().add(...):

player.getPoliticCards().add(getPoliticCards().get(0)); // inside drawPoliticCard(Player player) method

Here is the correct code sample:

PoliticCard.java

public class PoliticCard {
    private ArrayList<Color> politicCards;

    /**
     * @return the politicCards
     */
    public ArrayList<Color> getPoliticCards() {
        return politicCards;
    }
    /**
     * @param politicCards the politicCards to set
     */
    public void setPoliticCards(ArrayList<Color> politicCards) {
        this.politicCards = politicCards;
    }

    public void setDeck() {
        setPoliticCards(new ArrayList<Color>());
        getPoliticCards().add(Color.BLACK);
        getPoliticCards().add(Color.PURPLE);
        getPoliticCards().add(Color.BLUE);
    }

    public void drawPoliticCard(Player player) {
        player.getPoliticCards().add(getPoliticCards().get(0));
        getPoliticCards().remove(0);
    }

}

Bonus.java:

public class Bonus {
    protected int number; //The number of politic cards added in BonusPoliticCard
}

BonusPoliticCard.java

public class BonusPoliticCard extends Bonus {
    PoliticCard politicCard;
    public BonusPoliticCard(int number, PoliticCard politicCard) {
        this.number=number;
        this.politicCard = politicCard;
    }
    public void applyBonus(Player player){
        int i=0;
        while(i<number){
            politicCard.drawPoliticCard(player);
            i++;
        }
    }
}

Player.java

public class Player {
    private ArrayList<Color> politicCards;
    int num;

    public Player(int num) {
        this.num = num;
        politicCards = new ArrayList<Color>();
    }

    /**
     * @return the politicCards
     */
    public ArrayList<Color> getPoliticCards() {
        return politicCards;
    }

    /**
     * @param politicCards the politicCards to set
     */
    public void setPoliticCards(ArrayList<Color> politicCards) {
        this.politicCards = politicCards;
    }
}

BonusPoliticCardTest.java

public class BonusPoliticCardTest {

    @Test
    public void test() {
        PoliticCard politicCard = new PoliticCard();
        politicCard.setDeck();
        Bonus bonus = new BonusPoliticCard(3, politicCard);
        Player player = new Player(1);
        ((BonusPoliticCard) bonus).applyBonus(player);
        assertNotNull(player.getPoliticCards().get(2));
    }

}