Re: enums: What the H? again
- From: "George Cherry" <GWCherryHatesGreenEggsAndSpam@xxxxxxxxxxxx>
- Date: Sun, 17 Jul 2005 00:35:26 -0400
"Roedy Green" <look-on@xxxxxxxxxxxxxxxxxxxx> wrote in message
news:2ttid1dqnsdsim8ka459npl6jas658viuo@xxxxxxxxxx
> On Sat, 16 Jul 2005 15:55:11 -0400, "George Cherry"
> <GWCherryHatesGreenEggsAndSpam@xxxxxxxxxxxx> wrote or quoted :
>
>> Size s = Size.valueOf( Size.class, args[0] );
>
> You don't need that Size.class. You are using
> the internal method. Javac automatically generates you a method with
> this signature
>
> Size s = Size.valueOf( args[0] );
Thanks, Roedy. It does not seem very programmer
friendly to generate useful methods automatically
and not document their existence in either the Sun
tutorials or the docs.
> I puzzled over this, since I saw people using such a method but could
> find no sign of it in the Enum class until I did a decompile and saw
> it sitting there automatically generated.
Yes, it's automatically generated like the frequently
mentioned values() method which returns an array
of the type's constants. Does this mean I have to
decompile code to find out what really exists? I
think that sucks.
GWC
> Everything comes clear when you decompile an enum, and see the
> generated methods, and the inner classes for each enum constant.
>
> Most of the quirkiness of enum comes from the quirkiness of anonymous
> inner classes.
>
> here is a simple enum that involves no inner classes.
>
> package com.mindprod.htmlmacros;
>
> import java.util.EnumSet;
>
> /**
> * DO NOT SORT. THE ENUM ORDER IS SIGNIFICANT!! enum of possible
> Windows OSes.
> * May be used freely for any purpose but military.
> *
> * @author Roedy Green copyright 2005 Canadian Mind Products
> */
> public enum OS {
> /**
> * Windows 95
> */
> WIN95("W95", "Windows 95"),
> /**
> * Windows 98
> */
> WIN98("W98", "Windows 98"),
> /**
> * Windows Me
> */
> WINME("Me", "Windows Me"),
> /**
> * Windows NT
> */
> WINNT("NT", "Windows NT"),
> /**
> * Windows 2000
> */
> WIN2K("W2K", "Windows 2000"),
> /**
> * Windows XP
> */
> WINXP("WXP", "Windows XP"),
> /**
> * Windows 2003
> */
> WIN2K3("W2K3", "Windows 2003"),
> /**
> * Linux
> */
> LINUX("Linux", "Linux"),
> /**
> * Mac OS/0
> */
> CLASSICMAC("OS9", "classic MacIntosh OS/9"),
> /**
> * Mac OS X
> */
> MAC("OSX", "MacIntosh OS X");
>
> private String shortName;
>
> private String longName;
>
> private static boolean DEBUGGING = true;
>
> /**
> * Enum constant constructor that captures two extra facts about
> the enum.
> *
> * @param shortName
> * name for the os e.g. Me
> * @param longName
> * name of the OS e.g. "Windows XP"
> */
> OS( String shortName, String longName )
> {
> this.shortName = shortName;
> this.longName = longName;
> }
>
> /**
> * @return short name
> */
> public String getShortName ()
> {
> return this.shortName;
> }
>
> /**
> * @return long name
> */
> public String getLongName ()
> {
> return this.longName;
> }
>
> /**
> * Static method to construct a string mentioning multiple OSes,
> by slashes.
> *
> * @param choices
> * EnumSet of just the oses you want included
> * @return a String of the form "Windows 95/98/Me"
> */
> public static String slashList ( EnumSet<OS> choices )
> {
> StringBuilder sb = new StringBuilder( 40 );
> for ( OS o : choices )
> {
> sb.append( '/' );
> sb.append( o.shortName );
> }
> if ( sb.length() == 0 )
> {
> return "";
> }
> else
> {
> // chop lead /
> return sb.toString().substring( 1 );
> }
> }
>
> /**
> * test harness
> *
> * @param args
> * not used
> */
> public static void main ( String [ ] args )
> {
> if ( DEBUGGING )
> {
> // You don't use a constructor to create EnumSet objects.
> EnumSet<OS> justThese = EnumSet.of( WIN2K, WINXP, WINME );
>
> // prints "Me/W2K/XP"
> // note they come out in proper order.
> System.out.println( OS.slashList( justThese ) );
> }
> }
> }
>
> ---------------------------------------------------------
>
> decompilation.
> note generated valueOf, values, static finals for each enum constant,
> $VALUES array for indexing the constants, two hidden parms to each
> enum constant constructor, its name and ordinal.
>
> package com.mindprod.htmlmacros;
>
> import java.io.PrintStream;
> import java.util.EnumSet;
> import java.util.Iterator;
>
> public final class OS extends Enum
> {
>
> public static final OS[] values()
> {
> return (OS[])$VALUES.clone();
> }
>
> public static OS valueOf(String s)
> {
> return (OS)Enum.valueOf(com/mindprod/htmlmacros/OS, s);
> }
>
> private OS(String s, int i, String s1, String s2)
> {
> super(s, i);
> shortName = s1;
> longName = s2;
> }
>
> public String getShortName()
> {
> return shortName;
> }
>
> public String getLongName()
> {
> return longName;
> }
>
> public static String slashList(EnumSet enumset)
> {
> StringBuilder stringbuilder = new StringBuilder(40);
> OS os;
> for(Iterator iterator = enumset.iterator();
> iterator.hasNext(); stringbuilder.append(os.shortName))
> {
> os = (OS)iterator.next();
> stringbuilder.append('/');
> }
>
> if(stringbuilder.length() == 0)
> return "";
> else
> return stringbuilder.toString().substring(1);
> }
>
> public static void main(String args[])
> {
> if(DEBUGGING)
> {
> EnumSet enumset = EnumSet.of(WIN2K, WINXP, WINME);
> System.out.println(slashList(enumset));
> }
> }
>
> public static final OS WIN95;
> public static final OS WIN98;
> public static final OS WINME;
> public static final OS WINNT;
> public static final OS WIN2K;
> public static final OS WINXP;
> public static final OS WIN2K3;
> public static final OS LINUX;
> public static final OS CLASSICMAC;
> public static final OS MAC;
> private String shortName;
> private String longName;
> private static boolean DEBUGGING = true;
> private static final OS $VALUES[];
>
> static
> {
> WIN95 = new OS("WIN95", 0, "W95", "Windows 95");
> WIN98 = new OS("WIN98", 1, "W98", "Windows 98");
> WINME = new OS("WINME", 2, "Me", "Windows Me");
> WINNT = new OS("WINNT", 3, "NT", "Windows NT");
> WIN2K = new OS("WIN2K", 4, "W2K", "Windows 2000");
> WINXP = new OS("WINXP", 5, "WXP", "Windows XP");
> WIN2K3 = new OS("WIN2K3", 6, "W2K3", "Windows 2003");
> LINUX = new OS("LINUX", 7, "Linux", "Linux");
> CLASSICMAC = new OS("CLASSICMAC", 8, "OS9", "classic MacIntosh
> OS/9");
> MAC = new OS("MAC", 9, "OSX", "MacIntosh OS X");
> $VALUES = (new OS[] {
> WIN95, WIN98, WINME, WINNT, WIN2K, WINXP, WIN2K3, LINUX,
> CLASSICMAC, MAC
> });
> }
> }
>
> --------------------------------------------------------------
>
> Here is a more complicated enum with inner classes. Because this enum
> relies on static variables you can't have two of these beasts working
> independently. On my todo list is writing an essay on enums that will
> have to tackle how you would rewrite this avoiding that problem. One
> step at a time.
>
> Each enum constant implements the abstract how method a different way:
>
> package com.mindprod.stomp;
>
> /**
> * @author Roedy Green
> *
> * track current state of CD directory so we don't emit needless CD
> commands.
> */
> public enum InDir {
> /** we are in the project directory */
> INPROJECT() {
>
> String how ()
> {
> return "c:\ncd " + projectDir + "\n";
> }
> },
> /** we are in the root */
> INROOT() {
>
> String how ()
> {
> return "c:\ncd \\\n";
> }
> },
>
> /** we don't know (or care) which directory we are in */
> UNKNOWN() {
>
> String how ()
> {
> return "";
> }
> };
> /**
> * which directory we are in now
> */
> private static InDir currentState = UNKNOWN;
>
> /**
> * the fully qualified project directory. It cannot be private or
> * enum constants can't see it.
> */
> static String projectDir;
>
> /**
> * how you get to this directory
> *
> * @return possibly empty string of commands to get
> * to this directory
> */
> abstract String how ();
>
> /**
> * no arg constructor
> */
> private InDir( )
> {
> }
>
> /**
> * generate code to go to the given directory.
> * If we are already there, generates an empty string.
> *
> * @param wanted which directory we want go to next
> * @return commands to take us to that directory.
> */
> public static String _cd ( InDir wanted )
> {
> if ( wanted == currentState )
> {
> return "";
> }
> currentState = wanted;
> return wanted.how();
> }
>
> /**
> * @param projectDir
> * fully qualified project directory
> */
> public static void setProject ( String projectDir )
> {
> InDir.projectDir = projectDir;
> }
> }
>
> -----------------------------------------------------
>
> Here is the decompilation. Note how there are three places you can
> store information:
> 1. in the statics for the entire enum
> 2. in the instance variables used by all enum constants, each with
> their own copy.
> 3. in the anonymous inner class instance variables, specific to each
> enum constant.
>
> Note that because enum constants are anonymous inner classes, they are
> not allowed to have their own statics.
>
>
>
> package com.mindprod.stomp;
>
>
> public abstract class InDir extends Enum
> {
>
> public static final InDir[] values()
> {
> return (InDir[])$VALUES.clone();
> }
>
> public static InDir valueOf(String s)
> {
> return (InDir)Enum.valueOf(com/mindprod/stomp/InDir, s);
> }
>
> abstract String how();
>
> private InDir(String s, int i)
> {
> super(s, i);
> }
>
> public static String _cd(InDir indir)
> {
> if(indir == currentState)
> {
> return "";
> } else
> {
> currentState = indir;
> return indir.how();
> }
> }
>
> public static void setProject(String s)
> {
> projectDir = s;
> }
>
>
> public static final InDir INPROJECT;
> public static final InDir INROOT;
> public static final InDir UNKNOWN;
> private static InDir currentState;
> static String projectDir;
> private static final InDir $VALUES[];
>
> static
> {
> INPROJECT = new InDir("INPROJECT", 0) {
>
> String how()
> {
> return (new StringBuilder()).append("c:\ncd
> ").append(projectDir).append("\n").toString();
> }
>
> };
> INROOT = new InDir("INROOT", 1) {
>
> String how()
> {
> return "c:\ncd \\\n";
> }
>
> };
> UNKNOWN = new InDir("UNKNOWN", 2) {
>
> String how()
> {
> return "";
> }
>
> };
> $VALUES = (new InDir[] {
> INPROJECT, INROOT, UNKNOWN
> });
> currentState = UNKNOWN;
> }
> }
> ----------------------------------------------------------
>
> one of the anonymous inner classes looks like this:
>
>
> package com.mindprod.stomp;
>
>
> // Referenced classes of package com.mindprod.stomp:
> // InDir
>
> static final class InDir$1 extends InDir
> {
>
> String how()
> {
> return (new StringBuilder()).append("c:\ncd
> ").append(projectDir).append("\n").toString();
> }
>
> InDir$1(String s, int i)
> {
> super(s, i, null);
> }
> }
> --
> Bush crime family lost/embezzled $3 trillion from Pentagon.
> Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video.
> http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
>
> Canadian Mind Products, Roedy Green.
> See http://mindprod.com/iraq.html photos of Bush's war crimes
.
- Follow-Ups:
- Re: enums: What the H? again
- From: Roedy Green
- Re: enums: What the H? again
- References:
- enums: What the H? again
- From: George Cherry
- Re: enums: What the H? again
- From: Roedy Green
- enums: What the H? again
- Prev by Date: Re: setParameter for Applet
- Next by Date: Re: Fragile Fences
- Previous by thread: Re: enums: What the H? again
- Next by thread: Re: enums: What the H? again
- Index(es):
Relevant Pages
|
Loading