Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 5012262
Votes 40
Synopsis Using Strings and Objects in Switch case statements.
Category java:specification
Reported Against 1.4 , 1.4.2 , tiger-rc , tiger-beta
Release Fixed
State 6-Fix Understood, request for enhancement
Priority: 4-Low
Related Bugs 4032356 , 4276296 , 6404665 , 4269827 , 5029289
Submit Date 12-MAR-2004
Description




A DESCRIPTION OF THE REQUEST :
This proposal suggests changes to make the Java switch statement more useful.

See:
http://yost.com/computers/java/string-switch/
http://cdsmith.twu.net/professional/java/pontifications/switch.html

Normally you can't use Strings or Objects in javas switch statements.

I would like to use Strings in switches. Therefore I would like to see this introduced.

JUSTIFICATION :
It would make source code much easier  and elegant.

Now you would do this by using the strings hashcode instead of the strings, this has some impact on your ability to write fast code.

It would also be more easy to look at the source code and understand it.


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like to see this implemented:

switch(aString){
    case "strA":
         //Some code
}

ACTUAL -
Now you have to work around the limitation of using int's instead of String.

---------- BEGIN SOURCE ----------
public class SwitchTest{
    public static void main(String [] args){
        String input = "strA";
        switch(input){ //String input, can't do this NOW
            case "strA": //String cases, not workable NOW
                System.out.println("strA");
            case "strB":
                System.out.println("strB");
            }
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
First you can use a container:

Map strings = new HashMap();
strings.put("strA", new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        System.out.println("Dette er strA");
    }
});
strings.put("strB", new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        System.out.println("Dette er strB");
    }
});

String strInput = "strA";
ActionListener a = ((ActionListener) strings.get(strInput));
if (a != null) {
    a.actionPerformed(null);
}

You can also take the hashCode from the strings and do this:
switch(inputString){
case  3541040: //Hashcode of "strA"
    System.out.println("strA");
case 3541041: //Hashcode of "strB"
    System.out.println("strB");
}
(Incident Review ID: 243026) 
======================================================================




A DESCRIPTION OF THE REQUEST :
It would be nice if the 'switch' keyword could be applied to Strings and other static data types.  For example, it would be nice if the following were valid Java code:

public void process(String xmlTag)
{
    switch (xmlTag)
    {
        case "rootTag":
            ....
            break;
        case "embededTag":
            ....
            break;
        case "anotherTag":
            ....
            break;
    }
}

JUSTIFICATION :
This would make it so much easier to process XML where one must process differently a large number of peer tags.  While this can be done with if {} else if {} statemtnts or HashMaps, the former looks ugly and the latter is not always convenient.  I imagine this behaviour would find other beneficial uses too.
(Review ID: 310952)
======================================================================
Work Around
N/A
Evaluation
This is way outside the envelope of a switch.

  xxxxx@xxxxx   2004-03-31
I am making this the master request for strings in switch statements, since it has the most votes of the various duplicates and contains useful links and information.

See also the compilation scheme in 5029289, which expands on the use of hashcodes in this request, and 4032356, which proposes switching on classes.
Posted Date : 2007-02-26 17:39:57.0
Comments
  
  Include a link with my name & email   

Submitted On 01-OCT-2004
trejkaz
Enumerations are objects, and _those_ were permitted in the switch statement in 1.5.0.  If that's not already outside the envelope of a switch, I don't know what is.  The least that could be done is to make this consistent across all types.

Also, it doesn't help that C# has this language feature.  Many people who have been exposed to C# for even a short amount of time are going to find Java's switch statement pretty useless. :-)


Submitted On 11-MAR-2005
AlexLamSL
Well Enum types are compared by "==", so it is natural to be included into with the "switch" construct.

The suggestions here, which needs equals() instead, is a totally different problem.


Submitted On 18-MAY-2005
UlfZi
 For more readability I propose to extend the usage of the switch ... case statement for objects in concurrence to if ... else if ... else coding like the following syntax:

switch( myObject) {
  case CONSTANT1 : doSomething(); break;
  case CONSTANT2 : doSomethingElse(); break;
  default : doSomethingDefault();
}


case-statements should always test for identity as 


Submitted On 18-MAY-2005
UlfZi
 For more readability I propose to extend the usage of the switch ... case statement for objects in concurrence to if ... else if ... else coding like the following syntax:

switch( myObject) {
  case CONSTANT1 : doSomething(); break;
  case CONSTANT2 : doSomethingElse(); break;
  default : doSomethingDefault();
}


case-statements should always test for identity as "==" by default, for primitives and for objects.

For more flexibility I propose an additional syntax for testing on equality like:

switch( myObject) {
  case equals( CONSTANT1) : doSomething(); break;
  case equals( CONSTANT2) : doSomethingElse(); break;
  default : doSomethingDefault();
}


Example for Strings:

switch( myString) {
  case equals("black") : doSomething(); break;
  case equals("white") : doSomethingElse(); break;
  default : doSomethingDefault();
}


More additional syntax using other boolean methods of the class of the object given in the switch statement:

switch( myString) {
  case startsWith("b") : doSomething(); break;
  case startsWith("w") : doSomethingElse(); break;
  default : doSomethingDefault();
}


More additional usage of other boolean expressions on primitive types given in the switch statement like the following syntax:

switch( myPrimitiveInt) {
  case < 7 : doSomething(); break;
  case < 10 : doSomethingElse(); break;
  default : doSomethingDefault();
}


See:
http://forums.java.net/jive/thread.jspa?threadID=504


Submitted On 15-FEB-2006
AlexLamSL
-1
Agree with the Evalution - this is just not the way how switch statements work.


Submitted On 01-MAR-2006
Mark_McKay
+1  I think this would be a very useful and easy to read extension to Java.


Submitted On 14-FEB-2007
sjasja
-1

Use the Command pattern. If not appropriate, use if/else. If you find yourself doing a lot of switch/case structures, you may want to reconsider whether your code is structured in an object oriented manner. Also consider how switch-on-string encourages i18n-hostile code.

Switch-on-string proposals tend to have artificial examples of trying to match "strA", or at best Programming-101 "enter 'yes' or 'no'" examples. They lack a genuine often occurring programming problem that can't easily be implemented just as well or better using other means. That should tell us something...


Submitted On 20-APR-2007
trejkaz
Whether this is "the way switch statements work" or not is immaterial.

In this case what's happening is that the switch statement happens to use some kind of jump table and enum types happen to convert to integers which is why they work.

But when it comes to needing to compare a value against N string values, nobody gives a toss.  If the code compiles to exactly the same bytecode as you would get with a huge if/else block, then that's acceptable.

The Command pattern works in some situations, for others it's less than acceptable.  When you then resort to using if/else, you end up with code which would be much more readable if it were changed to a switch statement.


Submitted On 09-MAY-2007
Certainly Need this


Submitted On 20-JUN-2007
Switching on Strings is unnecessary in light of Enum.valueOf() and would actually encourage poor coding technique.

It would be much cleaner to maintain the list of possible String values as Enum tokens instead of sprinkling them into case statements.

See: http://www.xefer.com/2006/12/switchonstring


Submitted On 03-JUL-2007
+1

I tend to be a minimalist when coding, but so far as this RFE pertains to switch statements using Strings, I generally agree with trejkaz.

Extending 'switch' to include objects in general would be a semantic nightmare, given that the 'equals()' and like comparative statements can have all kinds of nasty side-effects. The String class, however, is immutable, fully maintained by Sun, and hasn't changed since forever. Using a string as the operand to the switch statement and string constants for each of the case arms can be made robust, unobtrusive, and efficient to compile. Let's face it, we can replace the mosh:

String sSomeString = some_lethargic_function_we_cant_call_much();
if( sSomeString.equals( "this" ) || sSomeString.equals( "that" ) )
    this_or_that();
else if( sSomeString.equals( "jump" ) || sSomeString.equals( "bigjump" ) )
{
    if( sSomeString.equals( "bigjump" ) )
        big();

    jump();
} else if( sSomeString.equals( "secondlastchance" ) ||
    sSomeString.equals( "lastchance" ) )
{
    last_chance();
} else do_default();

with

switch( some_lethargic_function_we_cant_call_much() ) {
    case "this":
    case "that":
        this_or_that(); break;

    case "bigjump":    big(); // fall
    case "jump":       jump(); break;
    case "secondlastchance":
    case "lastchance": last_chance(); break;
    default:           do_default();
}

C# has included the language feature for this very reason (as trejkaz mentions). I disagree with sjasja on the artificiality of the switch-string problem. Sir has likely never written a quick n' dirty parser or command interpreter.

I'll admit that I am mainly a proponent of the switch-on-string because of its intuitiveness. Languages are supposed to be simple but powerful. It's hard to explain to anyone new to a language why everyone knows what a switch-on-string does, many of us have (naively) tried to use it because other languages have it, and there can be absolutely no confusion or abuse of it, but that we should forget about it and use instead equally intuitive tools like hashmaps and if...else statements buried 18 layers deep.

I dare not mention that if Sun tweaks the compiler in the correct way, a switch-on-string statement can also be markedly more efficient than the 'if...else' ladder, especially for large ladders.


Submitted On 22-OCT-2007
How about creating a static singleton class like InternedStrings that implements the Enum interface?  Then your switch would be something like:

switch (Enum.valueOf(InternedStrings, myStringVariable)) {
case "StringLiteral1":
case "StringLiteral2":
case myInternedStringVariable:
}

You would be limited to either string literals or interned strings in your case, but the myStringVariable wouldn't need to be since Enum.valueOf(Class, String) would lookup for you the equivalent Enum value if it finds it in the interned strings table (null otherwise).


Submitted On 22-FEB-2008
Sanzennin
Well, Id say Strings should be allowed in swtich, or then make atleast switchString that supports strings, so everybody would be happy.

Idea of the Switch is, after all, to help the programmer get rid of huge pile of 
if (lots of stuff) { some stuff } else if (agen, lots of stuff) {some stuff}
Someone might even claim that the switch doesnt fill its purpose completely as it is now. 


Submitted On 10-MAY-2008
I also think this would be a very useful features. In developing software, I've gone around this issue a lot of times, using if's. But I've wondered why is not a Java feature yet? I think we should aim Java to a more syntactic sugar like language.
The "if" approach is all what we need to do the same thing that we do with switch in "ints", but nevertheless, we have the switch for ints, why not have it for "Object" using equals?


Submitted On 26-JUN-2008
This would be of really great help. This would make the code much more elegant and easy to understand. 


Submitted On 30-AUG-2008
sunburned
+1
Strings in Switch case statements would be a great enhancement to Java.  The inability to use strings has a definite detrimental impact upon code usability and maintainability.  

Consider the following scenario.  You want to use Java to process data from several different external sources such as text reports generated from a third party program, records from an outside database, and information from external web sources,.  The text report contains an entry with a string data code like "X" representing a certain classification of the item you are interested in, which is one of 32 possible codes (which may be more than one character as well as being alphanumeric).  Now, the database has half a million records, with varying record lengths -- the length being specified in another field of the record -- but the last field of the record is the field that contains the value corresponding to the "X" data code in the report.  Both the report and the database use the same classification system -- i.e. "X" in the report means the same as "X" in the database -- but the database only has 20 possible codes because it hasn't extended the classification scheme to include the 12 proprietary extensions that the third party software uses in its reports.

Now, to further complicate things, an external website contains a lot of useful information about items with the "X" classification along with 8 other types of the 32 text report item classifications.  You don't know why they only use 9 of the 32 (or 20 according to the database) classifications, but "X" still means "X". Only, "X" may be in position "1" of a web data possibility array of 9, position "5" of the database possibility array of 20, and position of "27" of a report possibility array of 32.  No matter where the data comes from, you still have to process 32 possible codes.  As it is now, you must use 32 if-then... blocks (possibly nested within other if-thens dealing with other code fields) to process the information.  It can be very difficult to read.

Using Switch case statements would make the code vastly easier to read, improve, and maintain.  To assign integer constants and values to the classification codes to allow the use of the Switch case in its current form is possible, but to do so increases the complexity of the java application, negating the benefits of the Switch case.  It would require adding special mapping code for the "X" item type specifier field because the "X" is in a different position in each differently sized possibility array.  This mapping code may have to be placed in more than one class and remain consistent among all classes that require it.  This problem becomes even more accute if one desires to write a jsp web application that can gather, process, and combine data from disparate sources.

This is a long submission on my part, but consider the number of lines required just to illustrate one case -- beyond the "Programming-101" reference made in an earlier posting -- of where the use of strings in Switch case statements would be an improvement.

Code maintenance is expensive, and the ability to use strings in the Switch case statement would absolutely make code easier to maintain.  It is also much less difficult to add functionality (especially important in the modern web application era) to code that is easier to read, which translates into lower cost.

This debate has been going on for over a decade now (see the related bugs) so I don't expect Java to change.  Unfortunately for me, because I have invested so much time in Java, the Switch case limitations (among other things) mean that Java Server Pages technology is a dead end for my web applications -- the improvement and maintenance costs would become too much.  I know that using the right tool for the job means that PHP is probably better suited to my needs than jsp.

But I also know this: no jsp equals no Sun servers for me in the future.


Submitted On 03-FEB-2009
Lasu
switch(inputString){
case  3541040: //Hashcode of "strA"
    System.out.println("strA");
case 3541041: //Hashcode of "strB"
    System.out.println("strB");
}

Now let's see why this will do not work:
System.out.println("aa".hashCode());
System.out.println("bB".hashCode());

Will result with:
3104
3104

So finally lets see more interesting workaround:

 enum Switch { 

    ONE("asd") { 
      @Override 
      public void action() { 
        System.out.println(this.text); 
      } 
    }// 
    , 
    TWO("bad")// 
    ; 

    protected String  text; 

    public void action() { 
      throw new NotImplementedException(); 
    } 

    Switch(String text) { 
      if (text == null) { throw new NullPointerException("text"); } 
      this.text = text; 
    } 

    public static Switch getByText(String text) { 
      if (text == null) return null; 
      for (Switch casee : Switch.values()) { 
        if (casee.text.equals(text)) return casee; 
      } 
      return null; 
    } 

    public static Switch getByTextForStartWith(String prefix) { 
      if (prefix == null) return null; 
      for (Switch casee : Switch.values()) { 
        if (casee.text.startsWith(prefix)) return casee; 
      } 
      return null; 
    } 

  }

http://lasu2string.blogspot.com/2009/02/using-strings-and-objects-in-switch.html


Submitted On 16-MAR-2009
ebresie
See project coin proposal:

http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000001.html



PLEASE NOTE: JDK6 is formerly known as Project Mustang