Re: enums: What the H? again




"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


.



Relevant Pages

  • Re: enums: What the H? again
    ... Everything comes clear when you decompile an enum, ... private String shortName; ... private static InDir currentState = UNKNOWN; ...
    (comp.lang.java.programmer)
  • A Class to get the name of Enum constant at runtime
    ... Dim rs As ADODB.Recordset ... You can get the description of an Enum form it's value. ... EnumName As String, ... Dim Idx As Long ...
    (microsoft.public.vb.general.discussion)
  • Enum enlightenment
    ... things about enum make sense. ... private String shortName; ... WindowsOS ...
    (comp.lang.java.programmer)
  • Re: A Question on VB Classes
    ... ' Use an enum if you want to control allowed values for Color ... Private m_Color As ColorEnum ... Public Property NameAs String ...
    (microsoft.public.dotnet.languages.vb)
  • EnumConverter interfering with Designer-Generated Code
    ... string representations of an enum's values. ... every enum whose values I desire to be displayed as localized ... "ShortDistance" but the Designer-Generated code looks like this: ... Design-Time or at Run-Time (so that I can use the localization ...
    (microsoft.public.dotnet.languages.csharp)

Loading