16

How many cases are possible for a switch statement in Java? For example if we are checking an integer how many case blocks are possible?

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Raji A C
  • 2,261
  • 4
  • 26
  • 31
  • 2
    Java 7 allows switch by strings too [check here](http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html). This allows unlimited numbers of switches. – Santosh Jun 14 '12 at 05:52
  • 2
    +1 Great question, hopefully not a dup. – dacwe Jun 14 '12 at 05:52
  • 2
    There is a upper limit for sure but when you are not going to have more than 20, why this question? Dont tell me you are writing a program to find Prime using case. – ejb_guy Jun 14 '12 at 05:53
  • See the accepted ans for this question. This ans your question in round-about way. http://stackoverflow.com/questions/4468388/maximum-number-of-enum-elements-in-java – ejb_guy Jun 14 '12 at 06:10
  • Do you **really** require an arbitrarily large amount of case blocks? It sounds to me like there is something wrong with your design. You should seriously ask yourself if there's a better way to solve whatever your problem is. – Doctor Jones Jun 14 '12 at 09:09
  • n number of switch cases where n is your requirement and finite number – Nandkumar Tekale Jun 14 '12 at 05:51

8 Answers8

15

The bound you will most likely meet first is that of the maximum number of entries in the constant pool per class which is 65535. This will allow for a few thousand case blocks of small complexity. The constant pool contains one entry for each numeric or string literal that is used at least once in the class but also one or more entries for all field, method and/or class reference as these entries are composed on behalf of other constants that must be present in the constant pool as well. I.e. a method reference entry consists of a reference to a string entry for the signature of the method and a reference to the class entry of the declaring class. The class entry itself again references a string entry for the class name.

See: Limitations of the Java virtual machine and The Constant Pool in the Java Virtual Machine Specification

The absolute upper bound for a switch ignoring or reusing the code in the case blocks is slightly less than 2^30 cases since each case has a jump target which is a signed 32 bit integer (see tableswitch and lookupswitch instructions) and thus needs 4 bytes per case and the byte code size for each method is limited to slightly less than 2^32 bytes. This is because the byte code is wrapped in a code attribute and the length of a attribute is given as a unsigned 32 bit integer. This size is fruther reduced because the code attribute has some header information, the method needs some entry and exit code and the tableswitch statement needs some bytes for itself with its min/max values and at most 3 bytes of padding.

x4u
  • 13,877
  • 6
  • 48
  • 58
  • Interesting answer (thanks for the links). However, does it apply to switch? The constant pool is used for the "layout of classes, interfaces, class instances, or arrays". A switch statement is likely to be compiled into a jump table (an array!) so the theoretical limit is 2 G-cases per switch and the constant pool limits only the number of arrays, i.e. the switch statements. Of course, in practice you'll run out of memory much earlier. – Igor F. Jun 14 '12 at 08:46
  • Yes, the case constants are located directly in the byte code and not in the constant pool but the code in each case block is likely to require some number of constant pool entries. You could of course try to minimize the use of constant pool entries, i.e. by compiling `5` as `4 + 1` or by invoking the same methods with the same arguments but in different order which would allow to work around the limited size of the constant pool. – x4u Jun 14 '12 at 10:10
  • But that limit applies to any Java class, not only switch statements, right? – Igor F. Jun 14 '12 at 10:22
  • Yes, I amended my answer with a paragraph about the hard limit for the number of switch cases if you would want to push it to the max on the expense that the resulting code would probably be of not much real world use anymore. – x4u Jun 14 '12 at 10:46
  • 2
    You're answering a question about limitations of the Java language by referring to limitations of bytecode which is plain _wrong_. There are plenty of Java compilers targeting other languages than bytecode. That should highlight the fact that [Java spec](http://docs.oracle.com/javase/specs/jls/se7/html/index.html) != [JVM spec](http://docs.oracle.com/javase/specs/jvms/se7/html/index.html). – aioobe Jun 14 '12 at 12:53
  • 1
    Actually the question does not ask for a Java *language* based answer explicitly and I guess it is reasonable to assume that a question about Java relates to a environment that is bound to the restrictions of the byte code format at some point if nothing else is specified in the question. – x4u Jun 14 '12 at 13:50
  • @aioobe read the description of the java tag. Where do you get the idea that the question is not jvm related? – josefx Jun 17 '12 at 11:45
7

There is no limit, except the size of your JVM to accommodate all the bytecode

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 2
    JVM spec != java spec. If the jvm imposees a limit where the Java spec does not, you can file a bug report on either javac or the jvm – aioobe Jun 14 '12 at 05:58
  • Yep Bohemian. I also assumed so. But couldn't find any place where it has been written. – ironwood Jun 14 '12 at 05:59
5

16377. At least for a simple code like:

public class SwitchLimit {

    public static void main(String[] args) {
        int x = 0;
        switch(x) {
        case 0:
        ...
        case 16376:
        default:
        }
        System.out.println("done.");
    }

}

You can have 16377 case statements in this example (not counting default) and if you add a case 16377:, the code won't compile with the following error:

The code of method main(String[]) is exceeding the 65535 bytes limit

As others pointed out, this number will probably be significantly lower if your method actually does anything that makes sense.

Dzinx
  • 55,586
  • 10
  • 60
  • 78
4

It depends on your requirement. you can have that many cases of range int type. As the range of int type is finite and after that concept of integer cycle will come into the picture.

As the size of int ranges from -2,147,483,648 to 2,147,483,647, so you can have a case for each number of them. So there is a limited number of case in case of integer.

But if you want to use String in case, then you can have unlimited number of cases as said by Bohemian.

Chandra Sekhar
  • 18,914
  • 16
  • 84
  • 125
2

The total number of cases will be maximum number that int can take depending on the hardware. Have a look at datatypes in java

So, you will have the entire range as possible number of case blocks.

Felix Christy
  • 2,179
  • 1
  • 19
  • 32
2

No limit of case statements in a switch. At worst you can get heap space but not in easy way.

manurajhada
  • 5,284
  • 3
  • 24
  • 43
  • 1
    Wrong. A Java method can contain a maximum of 65535 characters. – Nicktar Jun 14 '12 at 08:48
  • 1
    @Nicktar: :D Can you please share your research or something, As it is hard to believe!!! Personally I have seen 1800 lines method and dam sure that has many more characters then 65535. http://stackoverflow.com/questions/6570343/maximum-size-of-a-method-in-java – manurajhada Jun 14 '12 at 09:02
  • @manurajhada http://bugs.sun.com/view_bug.do?bug_id=4262078 The 65535 is the maximum size of the generated bytecode (not source code). There must be at least one byte of generated bytecode per switch case. Thus the limit must be less than 65535 cases. – emory Jun 14 '12 at 13:35
  • Yeah, i saw that bug when i was searching for the related information, and thats bytecode not the characters. Nicktar wrote about characters. Thanks Emory. – manurajhada Jun 14 '12 at 13:48
  • @manurajhada Yeah, characters is wrong. It has been a while since I researched the exception and memory failed me... It's bytes in the bytecode but that applies here too... – Nicktar Jun 15 '12 at 08:54
  • hmm thanks for the information Nicktar, really worth getting this. I am completely agree with you with the memory exception. – manurajhada Jun 18 '12 at 06:16
1

Reading the question, the answers, and the comments, I don't see why it is relevant. You can certainly have more cases than you can manually write. And, in the improbable case that you machine-generate your code, there are better choices than switches in Java.

Igor F.
  • 2,649
  • 2
  • 31
  • 39
-2

Infinite!! There is no such restriction.

Priyank Doshi
  • 12,895
  • 18
  • 59
  • 82
  • 3
    Not entirely true. There is an upper bound. – Blender Jun 14 '12 at 05:54
  • No, upper bound is defined by the maximum number of characters per method, which is 65535. Methods longer than that wouldn't compile, stating "Code too large to compile" or "code too large for try statement". – Nicktar Jun 14 '12 at 08:47
  • 3
    @Nicktar : Thats rubbish. There is not any logical upper bound. The maximum number of character in a method is another issue. – Priyank Doshi Jun 14 '12 at 08:53
  • 1
    @PriyankDoshi then could you please show me a switch statement with let's say 75000 cases (generated code would be perfectly ok)... – Nicktar Jun 15 '12 at 08:46