尝试在我的代码中修复堆栈溢出错误

时间:2013-11-19 21:32:43

标签: java arrays stack-overflow

我要做的是创建一个类来处理Card类定义的一副牌。为了让自己更容易,我将参数都设为整数,然后我创建了2个独立的(和私有的)toString方法,以赋予该值的String等价物。问题是,当我尝试运行我的测试类时,它给了我一个堆栈溢出错误。到目前为止,这是我的工作:

(我知道如果我愿意,我可以使用switch语句,但我没有牢牢掌握它们,我不想做错事。)

卡类:

public class Card {

private int cardNumber;
private int cardSuit;
private Card cardCard;

public Card(int cardNumber, int cardSuit){

    this.cardNumber = cardNumber;
    this.cardSuit = cardSuit;
    cardCard = new Card(cardNumber, cardSuit);

}


public String dealCard(){

    return ("The card is the " + cardCard.toStringCardNumber() + " of " + cardCard.toStringCardSuit() + ".");

}

private String toStringCardNumber(){

    if(cardNumber == 1){

        return ("Ace");

    }

    else if(cardNumber == 2){

        return ("2");

    }

    else if(cardNumber == 3){

        return ("3");

    }

    else if(cardNumber == 4){

        return ("4");

    }

    else if(cardNumber == 5){

        return ("5");

    }

    else if(cardNumber == 6){

        return ("6");

    }

    else if(cardNumber == 7){

        return ("7");

    }

    else if(cardNumber == 8){

        return ("8");

    }

    else if(cardNumber == 9){

        return ("9");

    }

    else if(cardNumber == 10){

        return ("10");

    }

    else if(cardNumber == 11){

        return ("Jack");

    }

    else if(cardNumber == 12){

        return ("Queen");

    }

    else if(cardNumber == 13){

        return ("King");

    }

    return null;

}

private String toStringCardSuit(){

    if(cardSuit == 1){

        return ("Diamonds");

    }

    else if(cardSuit == 2){

        return ("Hearts");

    }

    else if(cardSuit == 3){

        return ("Clubs");

    }

    else if(cardSuit == 4){

        return ("Spades.");

    }

    return null;

}


}

卡片类:

import java.util.Random;

public class DeckOfCards {

public DeckOfCards(){

    Card deckOfCardsArray[] = new Card[52];

}

public void createDeck(){

    for(int i = 1; i < 53; i++){

        if(i < 14){

            deckOfCardsArray[i] = new Card(i, 1);

        }

        else if(i >= 14 && i < 27){

            deckOfCardsArray[i] = new Card(i - 13, 2);

        }

        else if(i >= 27 && i < 40){

            deckOfCardsArray[i] = new Card(i - 26, 3);

        }

        else if(i >= 40 && i < 54){

            deckOfCardsArray[i] = new Card(i - 39, 4);

        }

    }

}


public void shuffleDeck(){

    Card tempCard1 = new Card(0, 0);
    int tempInt = deckOfCardsRandom.nextInt(53);

    for(int i = 0; i < 53; i++){

        tempCard1 = deckOfCardsArray[i];

        deckOfCardsArray[i] = deckOfCardsArray[tempInt + i];

        deckOfCardsArray[tempInt + i] = tempCard1;

    }

}

public String dealCard(int i){

    cardsRemaining--;

    return deckOfCardsArray[i].dealCard();

}

public int getCardsRemaining(){

    return cardsRemaining;

}

private Card[] deckOfCardsArray;
private int cardsRemaining = 52;
private Random deckOfCardsRandom;

}

测试类:

public class DeckOfCardsTest {


public static void main(String[] args) {

    DeckOfCards deckie = new DeckOfCards();

    deckie.createDeck();

    System.out.println(deckie.dealCard(5));

    System.out.println(deckie.getCardsRemaining());


}

}

具体错误是:http://pastie.org/8493772

有关导致问题的原因的任何想法?

5 个答案:

答案 0 :(得分:0)

在Card类的构造函数中,您将实例化另一个相同的Card对象。

您似乎没有引用Card对象的内部副本,因为没有它就无法做到这一点,所以只需删除该行就可以了。

这导致问题的原因是因为它正在形成一个循环,其中每个创建的卡都会导致另一张卡被创建,直到你如此深入地创建了这么多卡而溢出堆栈。

您似乎正在使用内部“cardCard”对象调用可在父卡上调用的函数,只需将'cardCard'替换为'this'或直接调用函数,如'toStringCardNumber()'而不是' cardCard.toStringCardNumber()”

答案 1 :(得分:0)

您需要从构造函数中删除此行:

cardCard = new Card(cardNumber, cardSuit);

每次创建Card时,它都会创建一个新的Card,它会创建另一个,等等。这将继续,直到你的堆栈空间不足并导致堆栈溢出。

您不需要班级中的cardCard字段。


此外,toStringCardNumber方法的切换案例如下所示:

switch (cardNumber) {
    case 1:
        return "Ace";
    case 2: 
        return "2";
    case 3:
        return "3";

    //... Put the remaining cases here

    default:
        return null;
}

答案 2 :(得分:0)

据推测,你正在其他课程中创建一张卡片,如下所示:

public class MyOtherClass
{
    public static void main(String[] args)
    {
        int rank = 2;
        int rank = 6;
        Card card = new Card(rank, suit);
    }
}

现在,在您的Card类中,当MyOtherClass已经实例化时,您尝试制作另一个Card对象,因此您将获得级联效果,其中一次尝试实例化Card会生成无限的新卡,直到您炸毁堆栈为止。< / p>

public Card(int cardNumber, int cardSuit){

    this.cardNumber = cardNumber;
    this.cardSuit = cardSuit;
    // This line is dangerously redundant. Don't do this. Ever.
    cardCard = new Card(cardNumber, cardSuit);

}

你的toString()应该运行如下:

public class Card
{
    // whatever code you already have

    public String toString()
    {
        String cardName = "";

        if(suit == 1)
        {
            if(cardNumber == 1)
            {
                cardName = "Ace of Spades";
            }
            else if(cardNumber == 2)
            {
                cardName = "Two of Spades";
            }
            // And so on... I think you get the idea
        }
        else if(suit == 2)
        {
        }

我真的鼓励您查看Java学习资料,并尝试更好地处理如何创建和使用Java对象。目前似乎有些东西已经逃脱了你的理解,但是更多的工作,我认为你将能够围绕这个概念进行思考。

答案 3 :(得分:0)

public Card(int cardNumber, int cardSuit){

this.cardNumber = cardNumber;
this.cardSuit = cardSuit;
cardCard = new Card(cardNumber, cardSuit);

}

这将永远继续(递归)。

删除

cardCard = new Card(cardNumber, cardSuit);

以及声明变量的位置。

private Card cardCard;

在您的deckOfCards类中,您可以创建Card对象 - 创建它并引用它的位置。您不需要在另一个Card对象中创建Card对象 - 无论如何您都不会引用它。

答案 4 :(得分:-1)

当没有更多的牌要处理时,你需要停止发牌。

public String dealCard(int i){

    cardsRemaining--;

    if(cardsRemaining >= 0) {
        return deckOfCardsArray[i].dealCard();
    }
}