![]() So I think it boils down to the fact enum came in first and was implemented with its ordinal begin at 0 due to which they couldn't support null value in switch block and later with String they decided to forced the same philosophy i.e. while generating the bytecode no null check was performed before calling hashcode() method). Later in Java1.7 ( Jul'2011) they followed ( forced) the same philosophy with String (i.e. Looks like they deferred ( ignored) this bug and eventually launched Java 1.5 in the same year in which they introduced 'enum' with ordinal starting at 0 and decided ( missed) not to support null for enum. If you look at the comment posted on that bug at Jun'2004, it says Don't hold your breath. ![]() (and hopefully interesting enough!!!)Įnum were first introduced in Java1.5 ( Sep'2004) and the bug requesting to allow switch on String was filed long back ( Oct'95). Very interesting and complicated way of implementing this functionality! ![]() This means, based on answers to Can Java's hashCode produce same value for different strings?, though rare, there is still a possibility of two cases being matched (two strings with same hash code) See this example below int monthNumber ģ1: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object )ZĤ0: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object )ZĪs you can see only one case gets generated for "Ea" and "FB" but with two if conditions to check for a match with each case string. 6: invokevirtual #18 // Method java/lang/String.hashCode:()I The output of the javap command below reveals that case is chosen based on the hashcode of the switch argument string and hence throws NPE when. This is an attempt to answer why it throws NullPointerException While String switches are implemented differently, the enum switch came first and set the precedent for how switching on a reference type should behave when the reference is null. However it hasn't been defined like that, and this definition can not be changed. Maybe it would've been a good idea to start counting the ordinals for enums at 1. ![]() A switch on the first enum value would be indistinguishible from null. That means, mapping null to 0 wouldn't be a good idea. The int value to switch on is determined by invoking the method Enum.ordinal(). And the "physical" argument to switch as well as its cases are ints. Under the hood, the switch statement will typically compile to a tablesswitch byte code. If we rather look at implementation details, this blog post by Christian Hujer has some insightful speculation about why null isn't allowed in switches (although it centers on the enum switch rather than the String switch): While the last sentence skips over the possibility of using case null:, it seems reasonable and offers a view into the language designers' intentions. In the judgment of the designers of the Java programming language, this is a better outcome than silently skipping the entire switch statement or choosing to execute the statements (if any) after the default label (if any). If the switch expression is of a reference type, that is, String or a boxed primitive type or an enum type, then a run-time error will occur if the expression evaluates to null at run time. The prohibition against using null as a switch label prevents one from writing code that can never be executed. As damryfbfnetsi points out in the comments, JLS §14.11 has the following note:
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |