jabedek jabedek - 26 days ago 12
Java Question

NullPointerException, can't find reason even after research

I'm having bad times with creating typical card/deck class in java. I've read some similar questions & answers but either they're not relatable/helpful or I can't simply comprehend it yet.
Here's the code

public class Cards {
boolean isAvailable;
int card_id;
static final int AC = 32;
public Cards [] deck = new Cards[AC];

public void set () {
int a = 0;
for (int i = 0; i < AC; i++) {
if(a == 4) a = 0;
deck[i].isAvailable = true; // <---------
deck[i].card_id = i + (a * 101); // <---------
a++;
}
}
public void read () {
for (int i = 0; i < AC; i++)
System.out.println(deck[i].isAvailable + " " + deck[i].card_id);
}
public static void main (String[] args) {
Cards c = new Cards();
c.set();
c.read();
}
}



Exception in thread "main" java.lang.NullPointerException

at Cards.set(Cards.java:13)

at Cards.main(Cards.java:24)


1.
I've read about similar issues and found that problem can be in initialization of an array and I've tried to do the same with my prog but it went bad anyway.

I marked 13th and 14th lines because they are being pointed (when i comment 13th line just for check, pointer sets to the next line).

2.
Next part of help I would like to get from you is:
Even though there is main (for training purposes), I see other class using this class (which just creates deck) so I guess I won't be needing main... Is everything well set besides probs in first point?

Answer

Very simple:

public Cards [] deck = new Cards[AC];

creates an empty array with AC number of slots for Cards objects.

Now you have to put a non-null Cards object into each slot!

But thing is: actually your abstraction is broken.

You wrote code that seems to take one card to be the same as a card set - by adding that array of Cards into your Cards class! And that makes it actually hard to fix your current code. As the "normal" way to fix this would be to add a constructor like

public Cards() {
  deck = new Cards[AC];
  for (int i=0; i<deck.length;i++) {
    deck[i] = new Cards();
}

If you try that ... you immediately run into an endless recursion (creating one new Cards would result in creating AC new Cards (to fill the array); causing a stackoverflow very soon.

Thus the real answer goes somewhere along these lines:

public class Card {
  ... a class that represents a SINGLE card in your game

and then

public card GameOfCards {
  ... a class that (for example!) uses an array to hold n objects of class Card!

Finally, as Peter is indicating in his comment: you should learn to use debugging means to work on such problems yourself. One good way: before using any data structure, iterate it and print out its content. Or even better, learn how to use a debugger, and walk through your code step by step! As you should please understand: this is very basic stuff; that you normally should not bring forward here.

Comments