• Post Reply Bookmark Topic Watch Topic
  • New Topic

case statement does not compile because middleName is not a final variable  RSS feed

 
Arend van der Kolk
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I am reading the book "JAVA Oracle Certified Associate Java SE 8 Programmer I Study Guide Exam 1Z0-808.pdf"

On page 76 they claim that the second case statement "case middleName" does not compile because middleName is not a final variable.

When i enter the code into my own IDE the 2nd case does compile fine. Can anybody explain me then if they are right/wrong about the keyword "final" and why?

Qoute: The second case statement does not compile because middleName is not a final variable, despite having a known value at this particular line of execution.

 
John Joe
Ranch Hand
Posts: 437
3
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you explain what you trying to achieve ?
 
Stephan van Hulst
Saloon Keeper
Posts: 7987
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think there was an update where the compiler could reason that a local String variable that wasn't being reassigned is effectively final. The compiler used at the time that passage in the book was written could not perform that reasoning.

Can you assign a new value to middleName before the switch statement, and see if it compiles?
 
Arend van der Kolk
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And i found it even more confusing that if i delete the following block from the switch stement both "case middleName" and "case lastName" do throw the compile error "case expressions must be constant expressions".

case 5: // DOES NOT COMPILE
id = 7; break;
case 'J': // DOES NOT COMPILE
id = 10; break;
case java.time.DayOfWeek.SUNDAY: // DOES NOT COMPILE
id=15; break;
 
Arend van der Kolk
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
John Joe wrote:Can you explain what you trying to achieve ?


I am not trying to achieve a goal with the code. It is the teacher in the book that shows us the different compiler errors to understand.
 
John Joe
Ranch Hand
Posts: 437
3
Android Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In case statement, we should only use number or char switch. You can't use a variable in your case statement.
 
Arend van der Kolk
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I can narrow down my question to: can you explain me this statement "case expressions must be constant expressions" ?
 
Arend van der Kolk
Ranch Hand
Posts: 78
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am getting the point John, thank you.

also when i found this new explanation it becomes more clear:



The case in the switch statements should be constants at compile time. The command

final int b=2
assigns the value of 2 to b, right at the compile time. But the following command assigns the value of 2 to b at Runtime.

final int b;
b = 2;
Thus, the compiler complains, when it can't find a constant in one of the cases of the switch statement.
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
John Joe wrote:In case statement, we should only use number or char switch.
That is incorrect; you can use an int or an enum constant or a String. If you try a narrower integer primitive type than int, it can be implicitly cast to an int, so chars are permitted. You can also use wrapper objects which can be unboxed to an integer primitive. You would appear to have a very out of date source of information.
You can't use a variable in your case statement.
The full details are in the Java® Language Specification (=JLS).
That JLS page wrote:Every case label has a case constant, which is either a constant expression or the name of an enum constant.
It doesn't say anything about being effectively final, but constant expression.
I tried your code and the case with middleName failed to compile. I had to remove most of the code and mark middleName final, which of course makes it a constant expression.

Which version of Java® are you using? If your code compiles, you have a faulty installation, or (much more likely) you didn't post exactly what you tried out.
 
Arend van der Kolk
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ritchie,

See .png attachment, i have version Java SE 8u121

Arend
SwitchStatementCode.PNG
[Thumbnail for SwitchStatementCode.PNG]
 
Arend van der Kolk
Ranch Hand
Posts: 78
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ritchie,

but if i comment out 3 cases (case 5, case 'J' and case java.ti....) then i do get the compile errors.
SwitchStatementCode2.PNG
[Thumbnail for SwitchStatementCode2.PNG]
 
Knute Snortum
Sheriff
Posts: 4279
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Arend van der Kolk wrote:Hi Ritchie,

See .png attachment, i have version Java SE 8u121

Arend

Case 5 doesn't compile because it's an int.
Case 'J' doesn't compile because it's a char
Case java....SUNDAY doesn't compile because it's an enum.

EDIT: and the switch statement is using a String to compare with.
 
Knute Snortum
Sheriff
Posts: 4279
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Arend van der Kolk wrote:Hi Ritchie,

but if i comment out 3 cases (case 5, case 'J' and case java.ti....) then i do get the compile errors.

To be considered a constant expression by the compiler, you have to declare and initialize on the same line.
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the first post, Arend van der Kolk wrote:. . . 2nd case does compile fine.  . . .
But then you showed screenshots (please don't) showing the code not compiling. We have been telling you all along that it doesn't compile because middleName isn't a constant expression (often called compile time constant). As Knute says, it must be declared and initialised to another constant expression (for example that literal) on the same line, and must be marked final. If you start line  with final, then that line will compile.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!