• Post Reply Bookmark Topic Watch Topic
  • New Topic

method values() for enum types  RSS feed

 
Greenhorn
Posts: 25
Java Netbeans IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What class does method Planet.values() in the code below belong to? I thought it belongs to java.lang.Enum but when I could not see it in Java API 7.


Thank you for your help.
 
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rod Taylor wrote:What class does method Planet.values() in the code below belong to? I thought it belongs to java.lang.Enum but when I could not see it in Java API 7.

Yes, it's an oddity that. You'll find it in the JLS, but not in the API - and I honestly don't know why. It might have something to do with the fact that an enum is not the same thing as an Enum (in the same way as there's no "array" class defined in the public API, yet we all learn about the 'length' attribute), but it seems unnecessarily confusing to me too.

But basically it returns an array of elements of the enum type it's called on (which is why you can use the "foreach" loop on it, and in your case are actually Enum<Planet>s).

Winston
 
Marshal
Posts: 56610
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The values method isn't declared in the Enum<T> class; the JLS chapter you quoted calls it implicitly declared. So I would presume it belongs to the Planet class the same way the .length field belongs to the [I class (for int arrays).
The situation appears different for valueOf which is both in that JLS link and the API for Enum<T>.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:The situation appears different for valueOf which is both in that JLS link and the API for Enum<T>.

I have a feeling that it has something to do with the fact that enums aren't exactly like other classes. Have you noticed that there seems to be an odd mix of "static"-like behaviour when you're overriding or defining methods?
For example: you can define a public method in a single instance of an enum, but you can't call it externally (or even internally), even using the correct instance name. The only place you can call it is from the instance itself; and it can't be qualified.

However, it still seems to me they could have declared a
public final Enum<T>[] values()
method (perhaps even labelled as "inherited" or "native") and saved us all a lot of confusion.

After all, there's the toArray(array) method in Collection, which is kind of analogous (and also tortuously defined, IMO).

@Rod: Just FYI - I'm pretty sure that it's never been declared; it's not just a 1.7 issue.

Winston
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
For example: you can define a public method in a single instance of an enum, but you can't call it externally (or even internally), even using the correct instance name. The only place you can call it is from the instance itself; and it can't be qualified.

That's because (or, at least, it's the way I interpret it) what is really happening when you add or override a method in an individual enum value is that you are creating an anonymous class that is a subclass of the enum. The new method is defined in that anonymous class. And because it's anonymous there is no way to refer to it from outside.

The complication with the values() method is that it's static. So if you define it in the Enum class it can't be inherited. What needs to happen is that when you declare an enum then a static values() method is generated for that class. The standard inheritance mechanisms in Java don't have a way of doing that, so it needs to be a special case.

Though I do think it should be documented somehow in the Enum class. The JLS is useful at times, but you shouldn't have to go there to find the definition of methods - those should be in the Javadocs.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Matthew Brown wrote:That's because (or, at least, it's the way I interpret it) what is really happening when you add or override a method in an individual enum value is that you are creating an anonymous class that is a subclass of the enum. The new method is defined in that anonymous class. And because it's anonymous there is no way to refer to it from outside.

Yeah, I kind of assumed it was something like that. There are also occasions where you get odd messages about not being able to access instance values from a static context though (don't have an example to hand, but if I find one I'll try and remember to post it), so there's plainly quite a bit of "building" going on in the background.

The complication with the values() method is that it's static.

Really? Then how does it return a typed array? It's not that I don't believe you; just that I can't seem to find any reference to how values() is declared, even in the JLS. If you could post the reference or link, I'd be most grateful.

I do think it should be documented somehow in the Enum class. The JLS is useful at times, but you shouldn't have to go there to find the definition of methods - those should be in the Javadocs.

Amen.

Winston
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
The complication with the values() method is that it's static.


It has to be static, doesn't it? Otherwise you couldn't call Planet.values(), you'd have to call it on an instance of the enum. But it's a static method that's "generated" within each new enum (I say "generated" because I've no idea of the actual mechanism). So if each values() method is specific to the owning enum, so it can be specifically typed to it.

The declaration is in Section 8.9.2 of the JLS (the first code block).
 
Matthew Brown
Bartender
Posts: 4568
9
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Matthew Brown wrote:That's because (or, at least, it's the way I interpret it) what is really happening when you add or override a method in an individual enum value is that you are creating an anonymous class that is a subclass of the enum. The new method is defined in that anonymous class. And because it's anonymous there is no way to refer to it from outside.

Yeah, I kind of assumed it was something like that.

Here's a quick demonstration:

Output is:
class test.Planet
class test.Planet
class test.Planet$1
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Matthew Brown wrote:The declaration is in Section 8.9.2 of the JLS (the first code block).

Aha! Missed it when I was browsing. Cheers for that. And all the other stuff you said makes sense too.

Winston
 
Rod Taylor
Greenhorn
Posts: 25
Java Netbeans IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for all who have contributed to this post!! Very much appreciated.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rod Taylor wrote:Thank you for all who have contributed to this post!! Very much appreciated.

You're most welcome.

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!