我已经阅读过有关空指针异常的帖子,但仍无法解决我的问题。
这是我为扑克游戏写的playCard课程。我有Card类和Deck类。
class Card {
/* constant suits and ranks */
static final String[] Suit = {"Clubs", "Diamonds", "Hearts", "Spades"};
static final String[] Rank = {"", "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
/* Data field of a card: rank and suit */
private int cardRank; /* values: 1-13 (see Rank[] above) */
private int cardSuit; /* values: 0-3 (see Suit[] above) */
/* Constructor to create a card */
/* throw MyPlayingCardException if rank or suit is invalid */
public Card(int rank, int suit) throws MyPlayingCardException {
if ((rank < 1) || (rank > 13))
throw new MyPlayingCardException("Invalid rank:" + rank);
else
cardRank = rank;
if ((suit < 0) || (suit > 3))
throw new MyPlayingCardException("Invalid suit:" + suit);
else
cardSuit = suit;
}
/* Accessor and toString */
/* You may impelemnt equals(), but it will not be used */
public int getRank() {
return cardRank;
}
public int getSuit() {
return cardSuit;
}
public String toString() {
return Rank[cardRank] + " " + Suit[cardSuit];
}
/* Few quick tests here */
public static void main(String args[]) {
try {
Card c1 = new Card(1, 3); // A Spades
System.out.println(c1);
c1 = new Card(10, 0); // 10 Clubs
System.out.println(c1);
c1 = new Card(10, 5); // generate exception here
} catch (MyPlayingCardException e) {
System.out.println("MyPlayingCardException: " + e.getMessage());
}
}
}
class Decks {
/* this is used to keep track of original n*52 cards */
private List<Card> originalDecks;
/* this starts with n*52 cards deck from original deck */
/* it is used to keep track of remaining cards to deal */
/* see reset(): it resets dealDecks to a full deck */
private List<Card> dealDecks;
/* number of decks in this object */
private int numberDecks;
/**
* Constructor: Creates default one deck of 52 playing cards in originalDecks and
* copy them to dealDecks.
* initialize numberDecks=n
* Note: You need to catch MyPlayingCardException from Card constructor
* Use ArrayList for both originalDecks & dealDecks
*/
public Decks() {
// implement this method!
ArrayList<Card> originalDecks = new ArrayList<Card>(52);
ArrayList<Card> dealDecks = new ArrayList<Card>(52);
Card card;
for (int i = 0; i <= 3; i++) {
for (int j = 1; j <= 13; j++) {
try {
card = new Card(j, i);
if (card != null) {
**originalDecks.add(card);**
}
} catch (MyPlayingCardException e) {
System.out.println("MyPlayingCardException: " + e.getMessage());
}
} //end of 1st for loop
} //end of 2nd for loop
dealDecks.addAll(originalDecks);
}
/**
* Constructor: Creates n decks (52 cards each deck) of playing cards in
* originalDecks and copy them to dealDecks.
* initialize numberDecks=n
* Note: You need to catch MyPlayingCardException from Card constructor
* Use ArrayList for both originalDecks & dealDecks
*/
public Decks(int n) {
int numberDecks = n;
Card card;
for (int m = 0; m < n; m++) {
for (int i = 0; i <= 3; i++) {
for (int j = 0; j <= 13; j++) {
try {
card = new Card(j, i);
if (card != null) {
**originalDecks.add(card);**
}
} catch (MyPlayingCardException e) {
System.out.println("MyPlayingCardException: " + e.getMessage());
}
}
}
}
dealDecks.addAll(originalDecks);
}
}
空指针异常发生在strong的行中,即card = new Card(j,i)。我读了这篇文章,认为我的问题是&#34; card = null&#34; case,所以我添加了&#34; if(card!= null)&#34;,但它没有解决问题。这里出了什么问题?
答案 0 :(得分:1)
您有两个Decks
构造函数,它们有两个不同的问题:
Decks()
构造函数(无参数): Deck()
构造函数中的这一行会创建一个本地变量,用于隐藏(隐藏)您的实例成员:
ArrayList<Card> originalDecks = new ArrayList<Card>(52);
这意味着您永远不会初始化您的实例成员,因此它会保留其默认值(null
)。如果您尝试对实例成员执行任何操作(例如,在该构造函数之外),则会因NPE而失败,因为您从未向实例成员分配任何内容。
您在该构造函数中突出显示的行不会抛出,因为它使用局部变量,而不是实例成员。
要初始化实例成员而不是在构造函数中声明和初始化局部变量,请删除返回类型,这样您就不会声明变量,而只是分配给您的实例成员:
originalDecks = new ArrayList<Card>(52);
dealDecks
存在同样的问题。
Decks(int)
构造函数:这个更简单:您永远不会分配给originalDecks
,因此它会保留其null
值,并且您突出显示的行会抛出。如果没有,则会在dealDecks.add
行之后抛出,因为您从未向dealDecks
分配任何内容。
这一位是主观的
第一个问题是我建议在引用实例成员时始终使用this.
的原因之一:
this.originalDecks = new ArrayList<Card>(52);
那样的方式A)很明显你正在处理实例成员而不是局部变量,而且B)所以你不能犯这个错误(因为ArrayList<Card> this.originalDecks = ...
会出现语法错误)。某些IDE和lint工具甚至有一个选项,您可以启用此选项,以便在实例mebers上不使用this.
错误或警告。