• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Liutauras Vilda
  • Bear Bibeault
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Piet Souris
  • salvin francis
  • Stephan van Hulst
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Jj Roberts

Why is setting this enum value to null legal?

 
Ranch Hand
Posts: 417
8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


I understand that myInt cannot be reassigned:  public static final Integer myInt = 1;


//Test.java:4: error: cannot assign a value to final variable myInt
 myInt = 10;  
 ^
1 error



But, if an enum is like a fixed set of constants, what does the following line (above and below) mean and why does it even compile to begin with?  Compile time constants are checked at compile time.  Right? And null as one of the fixed set of constants does not compile, yet it can be assigned to null (obviously).  

     Flavors STRAWBERRY = null;    

(corrected code from CSG Chapter 12#7)


 
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It seems to me you have mistaken the name you used on line 7 as being the same thing as the enum value you declared on line 3. They are not the same. The STRAWBERRY declared on line 7 is a local variable of type Flavors. It is legal to assign null to this.

Change the name on line 7 to something else, like flavor, for example.  The code will be logically/syntactically the same but semantically it will makes more sense.
 
Charles O'Leary
Ranch Hand
Posts: 417
8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:It is legal to assign null to this.


Why is setting this enum value to null legal?

I'm sorry, I may not have understood your point.  Please allow me to clarify my question.  How can "constants" be reassigned to null since null is not (and cannot more importantly be) within the fixed set of (predefined) constants?
 
Marshal
Posts: 71098
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I shall try explaining it. The enum element is called Flavour.STRAWBERRY (at least it would had Webster not taken the u out of flavour). Note the two parts of the name are joined together with the member operator (=dot). If you try to reassign Flavour.STRAWBERRY, the compiler will complain bitterly because, as you know, all enum elements are implicitly final.
What you have in line 7 is different: Flavour STRAWBERRY with a space in. That is a type and an identifier, which is a declaration of a new variable. I never knew you could pass null to a case.

Actually, JShell didn't much like my passing null; it threw an exception
 
Junilu Lacar
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Again, the STRAWBERRY declared on line 3 is NOT the same as the STRAWBERRY declared on line 7.  

On line 3, you have an enum value which is a constant value.  On line 7, you have a variable. Because STRAWBERRY (line 7) is a variable, you can assign it any of the enum values you defined on line 3, including CHOCOLATE and VANILLA. You can also assign it null. Semantically, assigning it null means there's no flavor. It's the same thing as assigning null to an object reference.

Using the name STRAWBERRY on line 7 makes the code confusing and misleading. If you rename the variable STRAWBERRY (line 7) to something that makes more sense, the code becomes less confusing.
 
Charles O'Leary
Ranch Hand
Posts: 417
8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Sybex CSG wrote:
When using an enum in a switch statement, the case statement must be made up
of the enum values only. If the enum name is used in the case statement value, then the
code does not compile.



For example, for the switch STRAWBERRY is acceptable but Flavors.STRAWBERRY is not.  

Campbell Ritchie wrote:Note the two parts of the name are joined together with the member operator (=dot). If you try to reassign Flavour.STRAWBERRY, the compiler will complain bitterly because, as you know, all enum elements are implicitly final.
What you have in line 7 is different: Flavour STRAWBERRY with a space in. That is a type and an identifier, which is a declaration of a new variable. I never knew you could pass null to a case.

Actually, JShell didn't much like my passing null; it threw an exception



Outside the switch, STRAWBERRY only refers to an object of type FLAVORS or not, where the assignment to null makes sense.

Campbell Ritchie wrote:I never knew you could pass null to a case.

Actually, JShell didn't much like my passing null; it threw an exception



Well I guess the compiler simply does not check for a non-null Flavor, but the JVM does!

Thanks Campbell and Junilu!
 
Junilu Lacar
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I never knew you could pass null to a case.

Actually, JShell didn't much like my passing null; it threw an exception



Right, you can't pass the literal null as a switch argument; that's a syntax error.

From the Java Tutorial: "A switch works with the byte, short, char, and int primitive data types. It also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap certain primitive types: Character, Byte, Short, and Integer" -- any of those that are reference types are allowed to be null.
 
Campbell Ritchie
Marshal
Posts: 71098
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The JLS (=Java® Language Specification) goes one further: it says that case XXX: throws an exception if you pass null.
 
Junilu Lacar
Sheriff
Posts: 15996
265
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:The JLS (=Java® Language Specification) goes one further: it says that case XXX: throws an exception if you pass null.


Interesting. It sure does. In JShell, the error is

Exception java.lang.NullPointerException: Cannot invoke "REPL.$JShell$14$Flavors.ordinal()" because "<parameter1>" is null


I guess that makes sense since you have to create that jump table somehow. Smells a little of leaky abstraction and a bit surprising that it wouldn't just fall through to the default case for a null enum.
 
Campbell Ritchie
Marshal
Posts: 71098
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:. . . a bit surprising that it wouldn't just fall through to the default case for a null . . .

Agree, but that's what the JLS says. It says, “…a run-time error will occur if the expression evaluates to null at run-time.” in the oldest JLS version I could find (=Java6). So that prohibition probably goes back to the earliest days of using reference types in cases, i.e. Java5. I can't find a Java5 version of the JLS.
 
Saloon Keeper
Posts: 12499
269
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's always annoyed me that you can't specify case null in the switch statement. It really doesn't seem that hard to implement.

It's too late now. Some code relies on the switch statement throwing an exception when null is passed.
 
Stephan van Hulst
Saloon Keeper
Posts: 12499
269
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Strike that, it should be possible to implement the switch statement in such a way that case null works for new code, and switch statements that don't contain such a case will still throw an exception.
 
Campbell Ritchie
Marshal
Posts: 71098
292
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
They would appear to have decided not to allow nulls and that's that.
 
I have a knack for fixing things like this ... um ... sorry ... here is a consilitory tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic