Question about Typesafe Enums

R

Rhino

I'm trying to incorporate some of the new features of Java 1.5 into some of
my existing classes but I'm somewhat confused about how to do something with
specific with typesafe enums.

The main article in the SDK documentation is
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html. Based on that
article, I'd like to go a beyond something they show in the Planets example.
I need the guidance of those of you who understand this better to tell me if
I can do what I want to do. I don't have the terminology straight in my mind
yet so forgive me if I don't articulate this correctly.

In the Planet enum that is shown in the article, they have a list of planets
and each planet has two specific values, a mass and a radius. The enum
provides methods mass() and radius() to get those values when they are
needed. Therefore, if I want to get the mass of the Earth, my class can get
it via Planet.EARTH.mass(), e.g.

System.out.println("The mass of the Earth is " + Planet.EARTH.mass());

So far so good. Now, would it be possible to set up other enums to
correspond to the values associated with the planets and use them to
reference the values? For example, could I create an enum called Mass that
was associated with the mass of each planet, then refer to the mass of a
specific planet via the new enum, something like this:

System.out.println("The mass of the Earth is " + Planet.EARTH.Mass);

I'm not wedded to the syntax in that last example; in fact, it looks a bit
nasty to me. I'm just trying to indicate that it would use the new Mass enum
instead of the mass() method to refer to the first value associated with the
given planet.

It would be neat to be able to avoid writing methods like mass() and just
use additional enums like Mass to refer to the specific facts that I want.
Basically, I'd like to be able to use meaningful words like Mass, rather
than numbers, as subscripts to the implied array that is in the Planet enum.

How could I do what I want to do? And, maybe more importantly, would it be a
good idea or would it cause problems?
 
H

Hendrik Maryns

Rhino schreef:
I'm trying to incorporate some of the new features of Java 1.5 into some of
my existing classes but I'm somewhat confused about how to do somethingwith
specific with typesafe enums.

The main article in the SDK documentation is
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html. Based onthat
article, I'd like to go a beyond something they show in the Planets example.
I need the guidance of those of you who understand this better to tell me if
I can do what I want to do. I don't have the terminology straight in mymind
yet so forgive me if I don't articulate this correctly.

In the Planet enum that is shown in the article, they have a list of planets
and each planet has two specific values, a mass and a radius. The enum
provides methods mass() and radius() to get those values when they are
needed. Therefore, if I want to get the mass of the Earth, my class canget
it via Planet.EARTH.mass(), e.g.

System.out.println("The mass of the Earth is " + Planet.EARTH.mass());

So far so good.
Indeed.

Now, would it be possible to set up other enums to
correspond to the values associated with the planets and use them to
reference the values? For example, could I create an enum called Mass that
was associated with the mass of each planet, then refer to the mass of a
specific planet via the new enum, something like this:

System.out.println("The mass of the Earth is " + Planet.EARTH.Mass);

I'm not wedded to the syntax in that last example; in fact, it looks a bit
nasty to me. I'm just trying to indicate that it would use the new Massenum
instead of the mass() method to refer to the first value associated with the
given planet.

I don´t think you can do this sort of hard-linking two enums together,
but you could define mass() to return something of type Mass, and in the
initialisation of Earth tell it to return Mass.EARTH_MASS.
It would be neat to be able to avoid writing methods like mass() and just
use additional enums like Mass to refer to the specific facts that I want.
Basically, I'd like to be able to use meaningful words like Mass, rather
than numbers, as subscripts to the implied array that is in the Planet enum.

Why would you want to have anything to do with those numbers? Although
they are used by the JVM internally, there is absolutely no to access
them. And how do you see this connected to Mass?
How could I do what I want to do?

What DO you want to do?

And, maybe more importantly, would it be a
good idea or would it cause problems?

Doesn´t seem like a good idea, but you are really unclear.

H.

--
Hendrik Maryns

==================
www.lieverleven.be
http://aouw.org
 
R

Rhino

Rhino schreef:
I'm trying to incorporate some of the new features of Java 1.5 into some
of my existing classes but I'm somewhat confused about how to do something
with specific with typesafe enums.

The main article in the SDK documentation is
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html. Based on
that article, I'd like to go a beyond something they show in the Planets
example. I need the guidance of those of you who understand this better to
tell me if I can do what I want to do. I don't have the terminology
straight in my mind yet so forgive me if I don't articulate this
correctly.

In the Planet enum that is shown in the article, they have a list of
planets and each planet has two specific values, a mass and a radius. The
enum provides methods mass() and radius() to get those values when they
are needed. Therefore, if I want to get the mass of the Earth, my class
can get it via Planet.EARTH.mass(), e.g.

System.out.println("The mass of the Earth is " + Planet.EARTH.mass());

So far so good.
Indeed.

Now, would it be possible to set up other enums to
correspond to the values associated with the planets and use them to
reference the values? For example, could I create an enum called Mass that
was associated with the mass of each planet, then refer to the mass of a
specific planet via the new enum, something like this:

System.out.println("The mass of the Earth is " + Planet.EARTH.Mass);

I'm not wedded to the syntax in that last example; in fact, it looks a bit
nasty to me. I'm just trying to indicate that it would use the new Mass
enum instead of the mass() method to refer to the first value associated
with the given planet.

I don´t think you can do this sort of hard-linking two enums together,
but you could define mass() to return something of type Mass, and in the
initialisation of Earth tell it to return Mass.EARTH_MASS.
It would be neat to be able to avoid writing methods like mass() and just
use additional enums like Mass to refer to the specific facts that I want.
Basically, I'd like to be able to use meaningful words like Mass, rather
than numbers, as subscripts to the implied array that is in the Planet
enum.

Why would you want to have anything to do with those numbers? Although
they are used by the JVM internally, there is absolutely no to access
them. And how do you see this connected to Mass?
How could I do what I want to do?

What DO you want to do?

And, maybe more importantly, would it be a
good idea or would it cause problems?

Doesn´t seem like a good idea, but you are really unclear.

H.

=================================================
I was going to intersperse my followups within your post, just like you did
to mine, but my newsreader isn't co-operating by putting >> in front of my
original words and > in front of your reply....

I'm sorry to be so unclear; like I said, I'm still strugging with the
terminology. Let me try explaining it a bit differently.

Okay, let's say we have an array called Planet and it looks like this (I'll
just use the inner planets to minimize typing):
Object[][] Planet = {
{"Mercury", 3.303e+23, 2.4397e6, 0},
{"Venus", 4.869e+24, 6.0518e6, 0},
{"Earth", 5.976e+24, 6.37814e6, 1},
{"Mars", 6.421e+23, 3.3972e6, 1}
};

In this array, the first column contains a planet name, the second column
contains the mass of the planet, the third column contains the radius of the
planet, and the fourth column contains the number of natural satellites that
the planet has.

If I want to know the number of satellites for the planet Mars, I can get it
via this: Planet[3][3]. But the meanings of the '3's in the subscripts are
not terribly obvious to someone looking at the code; no one would have any
way of knowing the _meaning_ of the fourth row or the fourth column of the
array.

I'd much rather be able to reference the number of satellies for a planet
with syntax that demonstrates a knowledge of the nature of the data, i.e.
the first column contains the planet's name, the fourth column is the number
of satellites, etc. To my way of thinking, this array has (implied) column
names and those column names comprise an enum consisting of the values NAME,
MASS, RADIUS, and SATELLITES. Also, the individual rows of the array can be
uniquely identified by the planet name which is therefore an implied enum
too, consisting of the values Mercury, Venus, Earth and Mars.

I'm not sure how the syntax should look but I'm picturing something that has
words from enums in place of numeric subscripts, something like this:
Planet["Mars"][SATELLITES], which means 'the number-of-satellites value from
the row of the array Planet whose key (first column value) is "Mars"'.

Again, this syntax is probably not entirely appropriate for maintaining
consistentcy with other syntax in Java but it gives the flavour I am
looking for.

I would also like to be able to use variables so that it would be possible
to loop through the array and list the number of satellites for each planet
without using a numeric subscript. Something like:

for (String name, int satellites : Planet) {
System.out.println("Planet " + name + " has " + Planet[NAME][SATELLITES]
+ " satellites.");
}

Sorry, I know that won't compile as it is. I'm not trying to make a firm
proposal on what the syntax should be, I'm just trying to convey the flavour
of what I'd like to do.

It seems to me that Enums are the vital ingredient in making this work but I
may be perverting them beyond their intended use. Or maybe there is a much
better way to do this without using Enums at all.

I'm just looking for some feedback on whether the concept I'm exploring even
makes sense and, if it does, how could I accomplish it with typesafe enums?

Rhino
 
R

ricky.clarkson

Planet[] planets=
{
new Planet("Mercury", 3.303e+23, 2.4397e6, 0),
new Planet("Venus", 4.869e+24, 6.0518e6, 0),
new Planet("Earth", 5.976e+24, 6.37814e6, 1),
new Planet("Mars", 6.421e+23, 3.3972e6, 1)
};

final class Planet
{
private final String name;
private final double mass;
private final double radius;
private final int satellites;

public Planet
(final String name,final double mass,final double radius,final
int satellites)
{
this.name=name;
this.mass=mass;
this.radius=radius;
this.satellites=satellites;
}

public String getName()
{
return name;
}

public double getMass()
{
return mass;
}

public double getRadius()
{
return radius;
}

public int numberOfSatellites()
{
return satellites;
}
}

Find a tutorial on OOP sometime.
 
R

Rhino

Planet[] planets=
{
new Planet("Mercury", 3.303e+23, 2.4397e6, 0),
new Planet("Venus", 4.869e+24, 6.0518e6, 0),
new Planet("Earth", 5.976e+24, 6.37814e6, 1),
new Planet("Mars", 6.421e+23, 3.3972e6, 1)
};

final class Planet
{
private final String name;
private final double mass;
private final double radius;
private final int satellites;

public Planet
(final String name,final double mass,final double radius,final
int satellites)
{
this.name=name;
this.mass=mass;
this.radius=radius;
this.satellites=satellites;
}

public String getName()
{
return name;
}

public double getMass()
{
return mass;
}

public double getRadius()
{
return radius;
}

public int numberOfSatellites()
{
return satellites;
}
}

Find a tutorial on OOP sometime.
Actually, I based my question on an article in the Java 1.5 SDK. I cited
that fact in the first post in this thread.

The code you provided is essentially the same as the code in that article,
which _doesn't_ answer my question.

Rhino
 
T

Thomas Hawtin

Rhino said:
System.out.println("The mass of the Earth is " + Planet.EARTH.Mass);

I'm not wedded to the syntax in that last example; in fact, it looks a bit
nasty to me. I'm just trying to indicate that it would use the new Mass enum
instead of the mass() method to refer to the first value associated with the
given planet.

I'm not entirely sure as to what you want here. An enum has a limited
set of values, but mass is a (near) continuous quantity. So, an enum of
mass doesn't make sense.

I'll assume you want an enumeration of properties (mass, radius, etc),
which can be applied to any Planet. So that you can write a method that
prints a property of a given planet, but is general to any property.
Here's a way to do that.

enum PlanetMeasure {
RADIUS {
public double of(Planet planet) {
return planet.radius();
},
MASS {
public double of(Planet planet) {
return planet.mass();
},
;
public abstract double of(Planet planet);
}

static void printPlanetMeasure(
Planet planet, PlanetMeasure property
) {
System.out.println(
"The "+property+" of "+planet+" is " +
property.of(planet)
);
}

(I was going to call the method "value" instead of "of", but that kind
of clashes with the namings of the enum infrastructure. I'm not entirely
happy with either. "of" is far too cute.)

Obviously, it gets more complicated if you want to use properties of
different types.

Tom Hawtin
 
R

Roedy Green

So far so good. Now, would it be possible to set up other enums to
correspond to the values associated with the planets and use them to
reference the values? For example, could I create an enum called Mass that
was associated with the mass of each planet, then refer to the mass of a
specific planet via the new enum, something like this:

no, but you could add a field or a method to the enum constants.

Unfortunately you can't extend an enum. So you have to modify the
original enum class code.
 
R

Rhino

Thomas Hawtin said:
Rhino said:
System.out.println("The mass of the Earth is " + Planet.EARTH.Mass);

I'm not wedded to the syntax in that last example; in fact, it looks a
bit nasty to me. I'm just trying to indicate that it would use the new
Mass enum instead of the mass() method to refer to the first value
associated with the given planet.

I'm not entirely sure as to what you want here.

Yeah, I'm not having a lot of luck articulating my wishes in a way that
seems clear even to me, let alone anyone else ;-)
An enum has a limited set of values, but mass is a (near) continuous
quantity. So, an enum of mass doesn't make sense.

I'll assume you want an enumeration of properties (mass, radius, etc),
which can be applied to any Planet.

Yes, that's right!

I didn't put it very well, did I? ;-) It obviously makes no sense to have an
enumerations that contains all the values possible for a planetary mass. I
should have made it clearer that I wanted to enumerate the _properties_ of a
planet. Those would be relatively few, such as mass and radius, and would
lend themselves better to an enum.

Then I want to use the names of the properties to access the actual values
so that I can say something like Planet.EARTH.MASS to get the mass of the
Earth.

So that you can write a method that prints a property of a given planet,
but is general to any property. Here's a way to do that.

enum PlanetMeasure {
RADIUS {
public double of(Planet planet) {
return planet.radius();
},
MASS {
public double of(Planet planet) {
return planet.mass();
},
;
public abstract double of(Planet planet);
}

static void printPlanetMeasure(
Planet planet, PlanetMeasure property
) {
System.out.println(
"The "+property+" of "+planet+" is " +
property.of(planet)
);
}

(I was going to call the method "value" instead of "of", but that kind of
clashes with the namings of the enum infrastructure. I'm not entirely
happy with either. "of" is far too cute.)
I *think* you're on the right track but....

I got several errors when I tried to compile the PlanetMeasure class in
Eclipse. Frankly, I'm somewhat confused by what you're doing (not surprising
since I've asked an unclear question!) that it wasn't obvious to me why
these errors were arising. I took a guess and found that the following
compiled fine, although I don't know if it changes the intent of your
code....

===============================================
public enum PlanetMeasure {

RADIUS {
public double of(Planet planet) {
return planet.radius();
}
},
MASS {
public double of(Planet planet) {
return planet.mass();
}
},
;
public abstract double of(Planet planet);

static void printPlanetMeasure(Planet planet, PlanetMeasure property) {
System.out.println("The " + property + " of " + planet + " is " +
property.of(planet));
}
}
================================================

Now, even if I've made reasonable alterations in the code, I'm not quite
clear how to use what you've done; how/where do I specify the _values_ of
the mass and radius for each of my planets so that I can get them back out
again with the of() method?
Obviously, it gets more complicated if you want to use properties of
different types.
If you can help me understand what you've done so far, I might be able to
work out the rest on my own....

Rhino
 
T

Thomas Hawtin

Rhino said:
I got several errors when I tried to compile the PlanetMeasure class in

Yup, I got my indentation and hence braces out.
Now, even if I've made reasonable alterations in the code, I'm not quite
clear how to use what you've done; how/where do I specify the _values_ of
the mass and radius for each of my planets so that I can get them back out
again with the of() method?

They're still in the original Planet enum. If you really wanted to, you
could switch on planet within each of the PlanetMeasures.of
implementations. Or (worse still), replace the "of" method with methods
for Mercury, Mars, ..., Xena.

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,538
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top