strange recursivion with enumerated types - how is this possible?

R

rfractal30

Hi

I was looking at 'enumerated types'in a tutorial and I came across some
strange recursive situations with I couldn't understand.

I can see the point of enumerated types as it limits the ways in which
an object can be instanciated. Take the code below. It would not be
possible to create an object like this:

monthes mymonth = new monthes("fred");

Obviously that does not work, because the constructor is private. Only
if I were creating an instance of monthes from within that class can I
do that. So I have enumerated types to create instances of monthes, for
example:

monthes mymonth = monthes.AUGUST;

This is fine, but it occured to me that this could lead to a weird kind
of recursion. I tested it and my suspicions turned out to be correct.
It was therefor possible to create code such as this:

System.out.println(mymonth.JANUARY.FEBUARY.MARCH.APRIL.NOVEMER.SEPTEMBER.JANUARY.JULY.DECEMBER.MAY.FEBUARY.getMonth());

Crazy!!! no? I really can't understand how this is possible (but I
tested it and it really is) How does this work? Why does the program
not crash due to infinite recursion. I'm confused.


//____________________________________________________
public class monthes {


static final monthes JANUARY = new monthes ("January");
static final monthes FEBUARY = new monthes ("Febuary");
static final monthes MARCH = new monthes ("March");
static final monthes APRIL = new monthes ("April");
static final monthes MAY = new monthes ("May");
static final monthes JUNE = new monthes ("June");
static final monthes JULY = new monthes ("July");
static final monthes AUGUST = new monthes ("August");
static final monthes SEPTEMBER = new monthes ("September");
static final monthes OCTOBER = new monthes ("October");
static final monthes NOVEMBER = new monthes ("November");
static final monthes DECEMBER = new monthes ("December");

private String month;
private int numDays;

private monthes(String inmonth) {


if (inmonth.equals("January") || inmonth.equals("March") ||
inmonth.equals("May") || inmonth.equals("July") ||
inmonth.equals("August") || inmonth.equals("October") ||
inmonth.equals("December")) {
numDays = 31;
}
if (inmonth.equals("April") || inmonth.equals("June") ||
inmonth.equals("September") || inmonth.equals("November")) {
numDays = 30;
}

if (inmonth.equals("Febuary")){
numDays = 28;
}

month = inmonth;
}

public String getMonth() {
return(month);
}
public int getNumDays() {
return(numDays);
}
}

}


public class TestMonthes {


public static void main(String[] args) {



monthes mymonth = monthes.AUGUST;


System.out.println(mymonth.JANUARY.FEBUARY.MARCH.APRIL.NOVEMER.SEPTEMBER.JANUARY.JULY.DECEMBER.MAY.FEBUARY.getMonth());

}

}
//____________________________________________________

Thanks for any advice.

Michael
 
R

rfractal30

rfractal30 said:
Hi

I was looking at 'enumerated types'in a tutorial and I came across some
strange recursive situations with I couldn't understand.

I can see the point of enumerated types as it limits the ways in which
an object can be instanciated. Take the code below. It would not be
possible to create an object like this:

monthes mymonth = new monthes("fred");

Obviously that does not work, because the constructor is private. Only
if I were creating an instance of monthes from within that class can I
do that. So I have enumerated types to create instances of monthes, for
example:

monthes mymonth = monthes.AUGUST;

This is fine, but it occured to me that this could lead to a weird kind
of recursion. I tested it and my suspicions turned out to be correct.
It was therefor possible to create code such as this:

System.out.println(mymonth.JANUARY.FEBUARY.MARCH.APRIL.NOVEMER.SEPTEMBER.JANUARY.JULY.DECEMBER.MAY.FEBUARY.getMonth());

Crazy!!! no? I really can't understand how this is possible (but I
tested it and it really is) How does this work? Why does the program
not crash due to infinite recursion. I'm confused.


//____________________________________________________
public class monthes {


static final monthes JANUARY = new monthes ("January");
static final monthes FEBUARY = new monthes ("Febuary");
static final monthes MARCH = new monthes ("March");
static final monthes APRIL = new monthes ("April");
static final monthes MAY = new monthes ("May");
static final monthes JUNE = new monthes ("June");
static final monthes JULY = new monthes ("July");
static final monthes AUGUST = new monthes ("August");
static final monthes SEPTEMBER = new monthes ("September");
static final monthes OCTOBER = new monthes ("October");
static final monthes NOVEMBER = new monthes ("November");
static final monthes DECEMBER = new monthes ("December");

private String month;
private int numDays;

private monthes(String inmonth) {


if (inmonth.equals("January") || inmonth.equals("March") ||
inmonth.equals("May") || inmonth.equals("July") ||
inmonth.equals("August") || inmonth.equals("October") ||
inmonth.equals("December")) {
numDays = 31;
}
if (inmonth.equals("April") || inmonth.equals("June") ||
inmonth.equals("September") || inmonth.equals("November")) {
numDays = 30;
}

if (inmonth.equals("Febuary")){
numDays = 28;
}

month = inmonth;
}

public String getMonth() {
return(month);
}
public int getNumDays() {
return(numDays);
}
}

}


public class TestMonthes {


public static void main(String[] args) {



monthes mymonth = monthes.AUGUST;


System.out.println(mymonth.JANUARY.FEBUARY.MARCH.APRIL.NOVEMER.SEPTEMBER.JANUARY.JULY.DECEMBER.MAY.FEBUARY.getMonth());

}

}
//____________________________________________________

Thanks for any advice.

Michael

Silly typo. Sorry :)
 
S

sanjay manohar

This is an excellent example of how stupid Java's syntax is!
whoever heard of a monthe being a member of another monthe?
 
J

John C. Bollinger

sanjay said:
This is an excellent example of how stupid Java's syntax is!
whoever heard of a monthe being a member of another monthe?

It isn't. The example exhibits the ability in Java to refer to a class
(static) variable or method by means of an expression of the
corresponding type. It is widely regarded as poor style to make use of
this capability, and some go so far as to consider it a misfeature of
the language. The main reason for that is that it is deceptive and
confusing: observe your own apparent misapprehension of the example,
just for starters.

If the months actually were members of each other, by the way, that
wouldn't be a syntax issue. It would be a question of the design of the
new Typesafe Enum feature.
 
C

Chris Uppal

Anthony said:
* This usage does not represent an example of enumerated
types. Java did not [until the latest version] sport such
types. This usage represents a convention that was
adopted to mimic this facility in Java, one that could
be criticised for being inefficient [i.e. needed several
object instances], [...]

I'm sure you (Anthony) know this, but I think your phrasing could be misleading
to others. The new "official" enumerated types in Java are syntactic sugar for
the old convention for implementing them. I.e. the costs, benefits[*], and
underlying semantics are identical. The difference is that the language-level
solution can be more thorough, and is known to the compiler, so that it can
conveniently "do the right thing" when it sees a switch statement for
instance.

([*] mostly; there's the unwarranted -- foolish, in my book -- restriction of
specifying behaviour for the enum objects.)

-- chris
 
A

Anthony Borla

Chris Uppal said:
Anthony said:
* This usage does not represent an example of enumerated
types. Java did not [until the latest version] sport such
types. This usage represents a convention that was
adopted to mimic this facility in Java, one that could
be criticised for being inefficient [i.e. needed several
object instances], [...]

I'm sure you (Anthony) know this, but I think your phrasing could
be misleading to others. The new "official" enumerated types in
Java are syntactic sugar for the old convention for implementing
them. I.e. the costs, benefits[*], and underlying semantics are
identical. The difference is that the language-level solution can
be more thorough, and is known to the compiler, so that it can
conveniently "do the right thing" when it sees a switch statement for
instance.

([*] mostly; there's the unwarranted -- foolish, in my book --
restriction of specifying behaviour for the enum objects.)

In truth I haven't had a chance to thoroughly explore the ins and outs of
1.5 [haven't even looked at generics - I still have C++ template-related
nightmares !], so I wasn't aware of the implementation issues you mentioned.
I may have been assuming more than I should have.

Thank you for pointing out those things, Chris. I'd much rather be corrected
now than inadvertantly spread not-quite-correct information in future posts.

Cheers,

Anthony Borla
 

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

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top