The next two code listings show String comparisons performed with the traditional if-else using equals approach and the newly available switching on strings approach.
StringsWithIfElseDemo.java
package dustin.examples;
import static java.lang.System.out;
/**
* Simple class demonstrating if/else comparisons of Strings.
*/
public class StringsWithIfElseDemo
{
/**
* Main executable function.
*
* @param arguments Command-line arguments: none expected.
*/
public static void main(final String[] arguments)
{
final String name = arguments.length > 0
? arguments[0]
: "Dustin";
if (name.equals("Dino"))
{
out.println("Flintstones?");
}
else if (name.equals("Neo"))
{
out.println("Matrix?");
}
else if (name.equals("Gandalf"))
{
out.println("Lord of the Rings?");
}
else if (name.equals("Dustin"))
{
out.println("Inspired by Actual Events");
}
else
{
out.println("The Good, the Bad, and the Ugly?");
}
}
}
StringsWithSwitchDemo.java
package dustin.examples;
import static java.lang.System.out;
/**
* Simple class demonstrating switch on Strings available with JDK 7.
*/
public class StringsWithSwitchDemo
{
/**
* Main executable function.
*
* @param arguments Command-line arguments: none expected.
*/
public static void main(final String[] arguments)
{
final String name = arguments.length > 0
? arguments[0]
: "Dustin";
switch (name)
{
case "Dino" :
out.println("Flintstones?");
break;
case "Neo" :
out.println("Matrix?");
break;
case "Gandalf" :
out.println("Lord of the Rings?");
break;
case "Dustin" :
out.println("Inspired by Actual Events");
break;
default :
out.println("The Good, the Bad, and the Ugly?");
}
}
}
In the "old" days (before JDK 7), the second class would not compile. When compilation of the code containing switching on Strings is performed, a compiler error is encountered that states "incompatible types" and shows that a "String" was "found" while an "int" was "required." This is shown in the next screen snapshot.
With JDK 7, the second class that switches on Strings does compile. In my case, I have compiled it using the "Developer Preview" (Milestone 12) version of JDK 7 (build 134). Project Coin enhancements were scheduled for Milestone 11.
Once both classes above are compiled, they can be executed as demonstrated in the next screen snapshot.
Both classes behave exactly the same whether the traditional if-then-else is used in conjunction with String.equals(Object) or the new switching on Strings is used.
The javap utility can be run against the class files generated for both versions of String comparison code shown above and the results do have some differences. The following screen snapshot demonstrates running this tool against those classes.
As the image above shows, the size of the output from
javap
is larger for the code with switch statements than the code for if-else statements. About the only significant conclusion that can be made based on that size difference alone is that the classes are not exactly the same (which was already evident from the size of the .class
files). I'm no expert at interpreting the output of the javap -v
command, but nothing sticks out to me that significantly differentiates one approach from another in terms of performance. It seems that the somewhat subjective measure of "readability" remains the main reason for choosing between if-else and switch on Strings.The Java documentation for switch is already updated with JDK 7 details. For example, it now states early on that "a switch works with the byte, short, char, and int primitive data types. It also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap certain primitive types: Character, Byte, Short, and Integer" (I added the emphasis). The documentation also states (again I have added the emphasis) that "an if-then-else statement can test expressions based on ranges of values or conditions, whereas a switch statement tests expressions based only on a single integer, enumerated value, or String object."
Perhaps the most significant new text in Java documentation on switch is the addition of an entire section of this document titled "Using Strings in switch Statements" that talks about using Strings with switches and provides a code example of this. This section also points out a few items that may be seem minor, but are worth noting. First, it points out that the String being switched on should be checked for null first to avoid a NullPointerException. In my example above, this was unnecessary because the ternary operator used to set the String variable being switched on ensured that either at least one command line argument was specified (which should not be null in normal use of 'main') or else initialized the String to a non-null value ("Dustin") if no command line arguments were specified. The second point worth keeping in mind is that the switch on Strings behaves as String.equals(Object) behaves rather than as String.equalsIgnoreCase(String) behaves. This is appropriate because Strings with different cases are not necessarily the same, but it also means that the only control the developer has over case sensitivity issues is to change the String to lowercase [String.toLowerCase()] or uppercase [String.toUpperCase()] before switching on it (and then ensure the Strings in the
case
are the same case). Checking the String first for null and then converting to the expected case are often necessary to ensure the desired behavior.The Desire for Switching on Strings
There is no question that some fellow Java developers are excited about the ability to switch on Strings. Two recent Java.net polls demonstrated this interest with 25% of respondents to the question "Which Project Coin (JSR 334) Java language enhancement will be most useful?" voting for the option "Strings in switch statements" (and 1/3 of respondents chose the "All of the above" option which obviously includes switching on strings). This was a follow-on to the previous Java.net poll question "What's the most important Java 7 enhancement for the work you do?" in which over half of all respondents voted for Project Coin.
Conclusion
I would have been much more likely to use the ability to switch on Strings several years ago before J2SE 5 made enums available to us. That being stated, there are times when I run into existing code or other situations where this ability can still increase code readability in a less risky and less costly way than redesign would require.
Không có nhận xét nào:
Đăng nhận xét