Reputation: 11639
I have a few questions regarding enumerated types in Java.
I'm working through a Java book and here is the code for building a deck of cards:
Here is how we could initialize an unsorted deck:
int[] suits = new int[52];
int[] values = new int[52];
int k=0;
for (int s=0; s<4; ++s) {
for (int v=2; v<=14; ++v) {
suits[k] = s;
values[k++] = v;
}
}
We could get a string describing each card with the following code:
static String[] suitNames = {"Spades", "Hearts", "Clubs", "Diamonds"};
static String[] faceCards = {"Jack", "Queen", "King", "Ace"};
static String getCardName (int s, int v) {
if (v <= 10)
return v + " of " + suitNames[s];
else
}
return faceCards[v-11] + " of " + suitNames[s];
The text goes onto say this:
Furthermore, suppose he or she writes the following:
System.out.println (getCardName(values[i],suits[i])); Note that the
value is being passed where the suit is expected, and vice versa. This code will compile correctly, but incorrect behavior will occur at runtime.
Why will there be an error at runtime? I don't see it? Doesn't the getCardName expect two integers as arguments?
More generally, what's wrong with this code? Why do we need enumerated types?
Here is the proposed code using enumerated types:
Suppose a file Suit.java contains the following:
public enum Suit {Spades, Hearts, Diamonds, Clubs};
First, is this how we declare variables of type enum?
This code says that a variable of type Suit can take on one of four values. We could then write the following code in another class.
Suit s = Suit.Spades;
Suit t = Suit.Hearts;
System.out.println ("The suits are " + s + " and " + t);
if (s.equals(t))
System.out.println ("The suits match.");
The output would be
The suits are Spades and Hearts
In doing the assignment into variables s and t, we had to say Suit.Spades and Suit.Hearts because Spades and Hearts were symbols defined only within the enumerated type Suit. The code for creating a deck of cards could then become the following:
Suit[] suits = new Suit[52];
int[] values = new int[52];
int k=0;
for (Suit s : Suit.values()) {
for (int v=2; v<=14; ++v) {
suits[k] = s;
values[k++] = v;
}
}
Is this code right? The k++ at the end increments k only after the value is used right?
Why is this code better?
Upvotes: 3
Views: 470
Reputation: 5829
The getCardName(int s, int v) has two int parameters. There are only 4 acceptable suit values; if you pass a suit value larger than four, you will get an Array out of bounds error at runtime.
The possible mistake is mixing the two parameters as described: Calling getCardName(v, s);
The compiler will not catch this; it is valid because both v and s are of type int.
The enum approach is better because the compiler will catch if you swap two arguments of different types (ie. a Suit and an int).
And yes, k++ increments AFTER, whereas ++k would increment prior.
Upvotes: 3
Reputation: 160191
(This is really a comment, but hard to read as such.)
Why will there be an error at runtime? I don't see it? Doesn't the getCardName expect two integers as arguments?
Yes.
What happens if they're in the wrong order?
Enumerated types are type safe by definition. You can't make the above class of error. They're easier to reason about. They can encapsulate functionality. See also What's the advantage of a Java enum versus a class with public static final fields?.
Upvotes: 1