0

I found that parentheses can be used in switch label, e.g.:

switch(id) {
  case (CONSTANT):
  case (1):
     // Do action
     break;
}

But why Java allow parentheses in this case, is there a use case ? because I can't use || or , to use multiple, e.g.

  case (CONSTANT||1):
  case (CONSTANT,1):

So why allow this syntax, I didn't find in JLS:

SwitchLabel:

case ConstantExpression :

case EnumConstantName :

default :

EnumConstantName:

Identifier
Community
  • 1
  • 1
Ori Marko
  • 56,308
  • 23
  • 131
  • 233
  • What is your reason for thinking it shouldn't? You can't use `||` because it isn't legal with integers. Nothing to do with `switch` or `case`. – user207421 Nov 05 '19 at 10:11
  • It is not a real use case (for me), but `case (CONSTANT + 2)` is possible if you haven't a case that handles the evaluated value already... It is of course possible without the parentheses, but maybe more readable having them. – deHaar Nov 05 '19 at 10:12
  • @user207421 I wouldn't expect `()` when not allowing multiple variables/constants – Ori Marko Nov 05 '19 at 10:12
  • @user7294900 The 'multiple variables/constants' you're trying to use aren't legal in any context. There are plenty that are legal here. – user207421 Nov 05 '19 at 10:13
  • @deHaar interesting, I can also use arithmetic on constants (CONSTANT * CONSTANT2) – Ori Marko Nov 05 '19 at 10:13
  • Yes, interesting... I'm especially interested in use cases for that ;-) – deHaar Nov 05 '19 at 10:14
  • @user207421 I mean similar to `if (id == CONSTANT || id == CONSTANT2)` – Ori Marko Nov 05 '19 at 10:14
  • For which you need two `case` statements with the same code. Not just made-up syntax that is semantically illegal. And there is still no reason why that illegality should make parentheses illegal. – user207421 Nov 05 '19 at 10:15

2 Answers2

3

Well, a ConstantExpression can contain parentheses:

A constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

  • ...

  • Parenthesized expressions (§15.8.5) whose contained expression is a constant expression.

  • ...

Hence, since any constant expression (whose type is char, byte, short, int, Character, Byte, Short, Integer, String, or an enum type) is allowed after case, parentheses are allowed.

Community
  • 1
  • 1
Eran
  • 387,369
  • 54
  • 702
  • 768
  • Thanks, is there a real use case for this option in switch? – Ori Marko Nov 05 '19 at 10:23
  • @user7294900 The 'use case' is that is is a valid constant expression, along with many other possibilities. No further reason requires. It is you that needs to answer the orginal question as to why it shouldn't be allowed. – user207421 Nov 05 '19 at 10:24
  • @user7294900 well, if you use a constant expression that combines multiple sub-expressions and operators, wrapping it with parentheses could be more readable. For example, you can write both `case (1 << 2) : break;` and `case 1 << 2 : break;`. I think the former is clearer. – Eran Nov 05 '19 at 10:25
  • @user7294900 More to the point, it could be *required* to get the intended precedence between subexpressions. – user207421 Nov 05 '19 at 10:27
  • @user7294900 well, inner parentheses are required for that, but the outer parentheses don't affect the result. For example, `1+2*3` and `(1+2)*3` will have different values due to different order of operations, but `1+2*3` and `(1+2*3)` will have the same value, so the parentheses in the latter example are not required. – Eran Nov 05 '19 at 10:32
  • So basically it's a optional syntax which isn't needed/required – Ori Marko Nov 05 '19 at 10:34
  • @user7294900 yes, it's optional. You could ask the same about the parentheses in `int i = (4);` – Eran Nov 05 '19 at 10:38
  • @user7294900 It isn't required in trivial cases. Sometimes it is, as I've already stated. – user207421 Nov 05 '19 at 10:46
  • @user207421 about intended precedence, Eran comment that *outer parentheses don't affect the result* – Ori Marko Nov 05 '19 at 10:53
  • @user7294900 I know what he wrote. I'm commenting on what you wrote. If parentheses were always optional and never affected the result they wouldn't be part of the language. You still haven't stated why you thought they shouldn't be allowed. – user207421 Nov 05 '19 at 11:01
1

The case just needs to be a constant expression. Something in parenthesis may be a constant expression.

private static final int TWO = 2;

public static void main(String[] args) {
    foo(3);
    foo(9);
}

private static void foo(int i) {
    switch (i) {
        case (TWO + 1):
            System.out.println("a");
            break;
        case (TWO + 1) * 3:
            System.out.println("b");
            break;
    }
}

CONSTANT || 1 is not allowed because integers are not valid operands of ||.

The comma syntax is not a thing.

Michael
  • 41,989
  • 11
  • 82
  • 128
  • Thanks, is there a real use case for this option in switch? – Ori Marko Nov 05 '19 at 10:31
  • 2
    You are approaching this from the complete wrong directly. A constant expression is already a well-defined concept and works fine here. To prohibit parentheses in this specific instance, the JLS would need to define a new concept: ConstantExpressionWithNoParenthesis. It complicates the spec and the language, and for what gain? To prevent people from wrapping a case statement in parenthesis when they might think it increases readability...? No thanks. – Michael Nov 05 '19 at 10:34