Search code examples
javareturncontrol-flow

How to go out of the conditional IF statement? Return doesn't work correctly


I have an example of a class. It creates a new card and puts it into the array. I want to control the number of cards and leave the flow if the number of cards is more than 54:

public class Card {
    private final String rank; 
    private final String suit;
    private String[][] cards;
    private static int NoC = 0;

    public Card(String suit, String rank) {
        if (NoC >= 54) {
        System.out.println("You cannot create any more cards");

        // and this "return" doesn't work correctly. NetBeans says "variable rank might not have been initialized"
        return;   
    }

    this.suit = suit;
    this.rank = rank;

    cards = new String[54][2];
    cards[NoC][0] = this.suit;
    cards[NoC][1] = this.rank;
    NoC = NoC + 1;
}

The program is compiled without errors. And works as I expect: if 55th card is being created it goes to the IF clause and prints the notice "You cannot create any more cards", but also it throws a warning "Uncompilable source code - variable rank might not have been initialized".

How to make it run correctly? Do I have to use smth else instead of return command?


Solution

  • If you want to prevent a 53rd card being created, you can't just return from the constructor - that would result in an improperly constructed object without the client noticing anything (how should the direct caller of the constructor know what was printed to stdout?). Instead, you need to throw an exception:

    public Card(String suit, String rank) {
        if (NoC >= 52) {
            throw new IllegalStateException("You cannot create any more cards");
        }
    
        this.suit = suit;
        this.rank = rank;
    
        cards = new String[54][2];
        cards[NoC][0] = this.suit;
        cards[NoC][1] = this.rank;
        NoC = NoC + 1;
    }
    

    IllegalStateException is just an example here - an existing runtime exception which you might reuse for this purpose. Or you may prefer defining and using your own (checked) exception instead.

    A better solution

    In general defining a type whose values are statically known and restricted, is best done using an enum. This avoids the whole problem above, because it is not possible to construct new enum values dynamically, so there is no need to check anything.