ligosan
ligosan

Reputation: 11

Java Arrays (java.lang.NullPointerException)

I'm getting this error on my java code, and I can't seem to figure out what I'm doing wrong..

java.lang.NullPointerException
at Race.toString(Race.java:94)
at TestA2Classes.start(TestA2Classes.java:39)
at TestA2.main(TestA2.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)

This is the code for one of the java files. The problem seems to be around the parts where I use the arrays.. What am I doing wrong?

public class Race {
public static final String[] RACE_DESCRIPTIONS = {"Sprint", "Distance", "Eliminator", "Keirin"};
public static final int SPRINT = 0;
public static final int DISTANCE = 1;
public static final int ELIMINATOR = 2;
public static final int KEIRIN = 3;
public static final int MAX_COMPETITORS = 8;

private int number;
private int typeIndex;
private MyDate date;
private boolean hasFinished;
private Competitor[] competitors;
private int numberOfCompetitors;

public Race(int number, int typeIndex, MyDate date) { 
    // TODO
    this.number = number;
    this.typeIndex = typeIndex;
    this.date = date;
    this.hasFinished = false;
    this.numberOfCompetitors = 0;
    Competitor[] competitors = new Competitor[MAX_COMPETITORS];

}

public int getNumber() {
    // TODO
    return number;
}

public boolean getHasFinished() {
    // TODO
    return hasFinished;
}

public int getTypeIndex() {
    // TODO
    return typeIndex;
}

public MyDate getDate() {
    // TODO
    return date;
}

public Competitor getCompetitor(int number) {
    // TODO
    Competitor competitor = competitors[0];
    for(int i=0; i<competitors.length; i++){
        if(competitors[i].getNumber() == number){
            return competitor;
        }
    }
    return null;
}

public void finishRace(int first, int second, int third) { 
    // TODO
    this.hasFinished = true;
    for(int i=0; i<competitors.length; i++){
        if(competitors[i].getNumber() == first){
            competitors[i].setPosition(1);
        } else if(competitors[i].getNumber() == second){
            competitors[i].setPosition(2);
        } else if(competitors[i].getNumber() == third){
            competitors[i].setPosition(3);
        } else{
            competitors[i].setPosition(0);
        }
    }
}

public boolean addCompetitor(Competitor competitor) {
    // TODO
    if(numberOfCompetitors < MAX_COMPETITORS){
        numberOfCompetitors++;
        return true;
    }
    return false;
}

public String toString() {
    // TODO

    String details = number + ", " + RACE_DESCRIPTIONS[typeIndex] + " [" + date + "]";
    if(hasFinished = false){
        details += ": Race not finished";
    } else if(hasFinished = true){
        details += "\n     1st: " + competitors[1].getName();
        details += "\n     2nd: " + competitors[2].getName();
        details += "\n     3rd: " + competitors[3].getName();
    }
    return details;
}

}

Upvotes: 1

Views: 155

Answers (2)

Suresh Atta
Suresh Atta

Reputation: 121998

Problem 1

In your constructor remove and move this to where you declared the array

 Competitor[] competitors = new Competitor[MAX_COMPETITORS];

Of course, you have to populate them ,before using it.

Problem 2

in toString() method

 if(hasFinished = false){
        details += ": Race not finished";
    } else if(hasFinished = true){
        details += "\n     1st: " + competitors[1].getName();
        details += "\n     2nd: " + competitors[2].getName();
        details += "\n     3rd: " + competitors[3].getName();
    }

You are initializing boolean variable's in if condition's. not comparing.

That should be

public String toString() {
    String details = number + ", " +  
                             RACE_DESCRIPTIONS[typeIndex] + " [" + date + "]";
    if(!hasFinished){
        details += ": Race not finished";
    } else{
        details += "\n     1st: " + competitors[1].getName();
        details += "\n     2nd: " + competitors[2].getName();
        details += "\n     3rd: " + competitors[3].getName();
    }
    return details;
}

Upvotes: 1

Juned Ahsan
Juned Ahsan

Reputation: 68715

Here is the problem in your constructor:

Competitor[] competitors = new Competitor[MAX_COMPETITORS];

You are NOT initializing the member variable competitors instead you are creating a local competitors variable in your constructor. So your instance array variable is not initialized and will be null. As your array will remain unitialized so Change the constructor as mentioned here:

public Race(int number, int typeIndex, MyDate date) { 
    // TODO
    this.number = number;
    this.typeIndex = typeIndex;
    this.date = date;
    this.hasFinished = false;
    this.numberOfCompetitors = 0;
    this.competitors = new Competitor[MAX_COMPETITORS];

}

As pointed by Rohit Jain in his comment, you have another problem in your code. You are not initializing your competitors array elements. If you are creating new elements then you need to do new for each of those elements otherwise your array will be not null but each competitor element will actually be null. Calling any method on such elements will cause NullPointerException.

Upvotes: 2

Related Questions