rgamber
rgamber

Reputation: 5849

static and final in java

I was reading about enumeration examples in Java from this page.

In the first example, the only part I did not understand was the use of the static keyword in this part of the code:

private static final List<Card> protoDeck = new ArrayList<Card>();

// Initialize prototype deck
static {
    for (Suit suit : Suit.values())
        for (Rank rank : Rank.values())
            protoDeck.add(new Card(rank, suit));
}

public static ArrayList<Card> newDeck() {
    return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
}

Why is the protoDeck declared static and final? Following that, a static loop is used to initialize the protoDeck. I know about static variables that they retain their values between instances of objects. But this is a singleton class (private constructor), so it cannot be instantiated.

So what is the benefit of doing it as above? what would be the implications if proteDeck is not static and final ?

Upvotes: 1

Views: 476

Answers (6)

OldCurmudgeon
OldCurmudgeon

Reputation: 65859

If protoDeck was not static there would be one for each Card and that would not be a good thing.

Obviously, you can only construct a static variable with static code.

final just means the protoDeck will never be replaced (although it can be changed internally).

Upvotes: 0

Nim
Nim

Reputation: 631

The final keyword in Java enables all kinds of compile-time magic. For instance, when the compiler knows that a variable will never be reassigned, it can perform "memoization" optimizations.

This alone is a good reason to final-ize local variables, parameters, and class members by default -- unless you really have to be able to reassign them, of course.

Upvotes: 0

SJuan76
SJuan76

Reputation: 24895

In the class initialization (the code in the static brackets) the program generates all the cards of the deck and stores it in protoDeck.

When newDeck is called, a shallow copy of the deck is returned. It means that all the cards object in the game are the same object (there is only one "Ace of Spades" card). They are managed in several different decks, though.

IMHO it is a little too complicated for this example, it would have more sense if instead of Cards where other kind of classes (one where initialization would be costly/expensive in RAM, or other where they were representing system resources -database connections or similar-).

Upvotes: 1

Hernan Velasquez
Hernan Velasquez

Reputation: 2820

The static { .... } portion of your code will be executed where your class is loaded by the Java Virtual Machine.

In your code segment, it's used to initialize the protoDeck ArrayList.

This is not following the Singleton pattern, since there's no evidence in your code that shows that the class is instantiated only one time.

Upvotes: 1

Has QUIT--Anony-Mousse
Has QUIT--Anony-Mousse

Reputation: 77485

Technically, this is not a singleton class. (A singleton has one instance, this one has none!)

It is a factory method for an ArrayList<Card>, and the method newDeck works the same way as a constructor would for a class "CardArrayList". It's not a Java constructor but a factory method, but other than that it serves the same purpose: creating new card decks.

Using a class CardArrayList and subtyping ArrayList would obviously be an alternative. Try this as an exercise: write such as class so that it serves the same purpose. Try to use a constant (static final) for keeping the initial set of objects. You'll notice that there is little difference between these two, except that this approach clearly says that there is no added functionality, but the result is "nothing but an ArrayList<Card> containing a full deck". Subclassing might imply that there is extra functionality, such as ensuring the deck is not messed with.

The static final variable contains the prototype that serves as template for new objects.

Upvotes: 2

Jeanne Boyarsky
Jeanne Boyarsky

Reputation: 12266

If it isn't static, the code won't compile because the newDeck method is static, And newDeck is static because you don't get a different deck for different cards.

Making it not final wouldn't do anything different. It's final in that you can't assign a different array. But you can still add to it, so it isn't immutable. So it is a common clue, but not a change in behavior.

Upvotes: 0

Related Questions