PersistenceDelegate for typesafe enum pattern

I've converted my code over from using int constants to the typesafe enum pattern in Effective Java. Unfortunately, the pattern only goes into serialization using Serializable and does not go into how to write a proper PersistenceDelegate that parallels the safety precautions of the Serializable enum. I've tried to do a direct mirroring of the readResolve() method given in the book inside of the intiatiate method of my PersistenceDelegate, but the XMLEncoder keeps rejecting the output and I get an InstantiationException, which shouldn't happen since the method call should not instantiate any new instances since the enums are static.
class PositionBiasModePersistenceDelegate extends PersistenceDelegate {
    protected Expression instantiate(Object oldInstance, Encoder out) {
        PositionBiasMode mode = (PositionBiasMode) oldInstance;
        return new Expression(mode, PositionBiasMode.VALUES, "get", new Object[] {new Integer(PositionBiasMode.VALUES.indexOf(mode))});
public abstract class PositionBiasMode {
    private final String name;
    private static int nextOrdinal = 0;
    private final int ordinal = nextOrdinal++;
    /** Creates a new instance of PreferredPositionMode */
    private PositionBiasMode(String name) {
        this.name = name;
    public String toString() {
        return name;
    public abstract boolean complies(PositionBias pb);
    public static final PositionBiasMode IGNORE = new PositionBiasMode("Ignore") {
        public boolean complies(PositionBias pb) {
            return true;
    public static final PositionBiasMode FRONT = new PositionBiasMode("Front") {
        public boolean complies(PositionBias pb) {
            return pb.hasBias() && pb.getPositionBias() < 0 ? false : true;
    public static final PositionBiasMode BACK = new PositionBiasMode("Back") {
        public boolean complies(PositionBias pb) {
            return pb.hasBias() && pb.getPositionBias() >= 0 ? false : true;
    private static final PositionBiasMode[] PRIVATE_VALUES = {IGNORE, FRONT, BACK};
    public static final List VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
}

Yeah I tried this too. I think the instantiation exception is something to do with it trying to recreate the MyEnum.VALUES List. I don't understand enough about the process to know how to fix that though.
The approach I eventually went for was to add a couple of things to the enum class as follows:
// add to MyEnum class:
public static final PersistenceDelegate PERSISTENCE = new PersistenceDelegate()
     protected boolean mutatesTo(Object oldInstance, Object newInstance)
          return (MyEnum)oldInstance == (MyEnum)newInstance;
     protected Expression instantiate(Object oldInstance, Encoder out)
          MyEnum enum = (MyEnum)oldInstance;
          return new Expression(enum, new MyEnum.Factory(), "forOrdinal", new Object[]{new Integer(enum.ordinal)});
public static final class Factory
     public MyEnum forOrdinal(int ordinal)
          return PRIVATE_VALUES[ordinal];
// usage:
XMLEncoder enc = new XMLEncoder(...);
enc.setPersistenceDelegate(MyEnum.class, MyEnum.PERSISTENCE);Not entirely sure it's the ideal approach but maybe it'll work for you. Cheers.

Similar Messages

  • The predecessor to the "typesafe enum pattern"

    In 1998, Michael Bridges published the following on Dr.Dobb's Portal
    (http://www.ddj.com/windows/184403569):
    class BookAgeLevel
    private BookAgeLevel(){}    
    // Following are all the BookAgeLevel objects    
    // there will ever be.    
    final static BookAgeLevel TODDLER = new BookAgeLevel();    
    final static BookAgeLevel CHILD = new BookAgeLevel();    
    final static BookAgeLevel TEENAGER = new BookAgeLevel();    
    final static BookAgeLevel ADULT = new BookAgeLevel();    
    }In 1999, Nigel Warren and Philip Bishop refers to the exact same pattern as the "typesafe
    constant idiom" in their book "Java in Practice" (page 48):
    public final class Alienrace
      public static final AlienRace BORG = new Alienrace();
      public static final AlienRace FERENGI = new Alienrace();
      private AlienRace() {}
    }In 2000, Joshua Bloch refers to the following code as the "typesafe enum pattern" (http://java.sun.com/developer/Books/shiftintojava/page1.html):
    // The typesafe enum pattern
    public class Suit {
        private final String name;
        private Suit(String name) { this.name = name; }
        public String toString()  { return name; }
        public static final Suit CLUBS = new Suit("clubs");
        public static final Suit DIAMONDS = new Suit("diamonds");
        public static final Suit HEARTS = new Suit("hearts");
        public static final Suit SPADES = new Suit("spades");
    }

    sunfun99 wrote:
    No point, just interesting. There is no question attached to this.OK - I still have a load of code in both C++ and Java that uses this Pattern ( it ain't broke so I ain't fixing it) and I first started using this in C++ in about 1987 (God 20 years ago). I didn't invent it for myself so it must be older than that.

  • Typesafe enum pattern

    Hi all,
    In the “Effective Java Programming Language Guide” by: “Joshua Bloch”, chapter: 5, item: 21, I came across the following:
    +“Constants maybe added to a typesafe enum class w/o recompiling its clients b/c the public static object reference fields containing the enumeration constants provide a layer of insulation bet. the client and the enum class.+
    What does that mean?
    The constants themselves are never compiled into clients as they are in the more common int enum pattern and its String variant.”
    What does that mean?
    Can someone please explain the above in more detail or guide me in another doc./article which helps me get the point?
    Any help is greatly appreciated.
    Edited by: RonitT on Apr 20, 2009 2:53 PM

    In any case, that item should be updated now to advise you to use the Enum types introduced in 1.5 instead of rolling yer own. You are right, I'll use that instead - looks like I have an old edition of book!
    Anyway. just for me to understand what you mentioned, since the client code sees the value of RANDOM -- like 17 and not 42 -- so let say my client code has the constants 0 thru 10 and now I need to add new constants from 11 to 20, if I'm confident that my client will never need these new constants, I don't need to give them the new code which contains the values 11 thru 20, is that right? That was you were trying to tell me?
    Thanks again.

  • ORing TypeSafe enums together

    I have tranaslated an enum type from C using the "typesafe enum pattern" (see, e.g. Bloch: Effective Java, p.104). I want to OR two of the enum values together. E.g.
    Classname.FIRST | Classname.SECOND
    but because they are instances of a class and not int values I get an "operator cannot be applied..." error from the compiler. How can I augment/modify the class to make this operation legal and correct?
    Many thanks.

    You would need to associate an integer ordinal with each enum. Josh demonstrates something like this later in the chapter for an enum that implements Comparable. Since you want to work with bitwise values, you'll need to make each successive ordinal a power of two so each enum maps to one bit. It might look something like this: public class MyEnum implements Comparable {
        /** ordinal of next enum to be created */
        static private int nextOrdinal = 1 ;
        /** returns next ordinal to assign */
        static private int getNextOrdinal() {
            int thisOrd = nextOrdinal ;
            nextOrdinal <<= 1 ;
            return thisOrd ;
        /** face name of this enum */
        private final String name ;
        /** bitwise ordinal for this enum */
        private final int ordinal = getNextOrdinal() ;
        private MyEnum(String name)    { this.name = name ; }
        public String toString()       { return name ; }
        public int getOrdinal()        { return ordinal ; }
        public int compareTo(Object o) { return ordinal - ((MyEnum)o).ordinal ; }
        static public final MyEnum FIRST  = new MyEnum("First") ;
        static public final MyEnum SECOND = new MyEnum("Second") ;
        static public final MyEnum THIRD  = new MyEnum("Third") ;
        static public final MyEnum FOURTH = new MyEnum("Fourth") ;
    } Then, two enums are "OR'd" together like so: MyEnum.FIRST.getOrdinal() | MyEnum.SECOND.getOrdinal().

  • Typesafe enums - 1.5

    In the interview Joshua Bloch states the the new 1.5 feature "Typesafe enums - Provides all the well-known benefits of the Typesafe Enum pattern"
    Does it also provide the pitfalls? The typesafe enum pattern is nice. However, in a multi-classloader environment it can behave unexpectedly. Similar to the Singleton pattern, it is generally best to avoid it in app-server code.
    Does the 1.5 implementation essentially compile to the pre-1.5 manual implementation or does it deal with this issue?

    you can overcome the and .equals() failing with a very minor amount of code. Basically you need a set of all possible typesafe values.
    Additionally you need to implement readResolve to prevent serialization from cloning.
    Finally - it's just never a good idea to use == for equality comparison. It should only be used for identity comparison (and even then most of the time you should have equals perform the identity comparison).
        private static final Stooge[] ALL = new Stooge{Moe, Larry, Curly};
        //see java.io.Serializable for details
        protected Object readResolve() throws ObjectStreamException {
            return getTypeFor(this.name);
        //you usually need this for retrieval from persistent storage
        public static Stooge getTypeFor(String name){
          Stooge result = null;
          for(int i = 0; i < ALL.length; i++){
            if(ALL.name.equals(name)){
    result = ALL[i];
    break;
    return result;

  • Mapping typesafe enums

    I have a class, one of it's attributes is a typesafe enum:
    public class Title {
         TitleType type;
         int titleId;
         String titleName;
         public TitleType getTitleType() {
              return this.type;
    public class TitleType {
         private final String name;
         private final int typeId;
         private TitleType(String name, int typeId) {
              this.name = name;
              this.typeId = typeId;
         public String toString() {
              return this.name;
         public int toInt() {
              return this.typeId;
         public static final TitleType MAIN_TITLE = new TitleType("MAIN", 1);
         public static final TitleType SUB_TITLE = new TitleType("SUB", 2);
    }My table is:
    TITLES (
    title_id numeric,
    title_type varchar,
    title_name varchar)
    How do I map the TitleType class/attributes' String value to the column title_type in titles?
    For a title with TitleType TitleType.MAIN_TITLE my table should look like:
    title_id     title_type     title_name
    1          MAIN          "The Guiness book of records"Regards,
    Anthony

    Thanks Doug,
    I created the AfterLoad class and unmapped the field.
    For some reason though all the titles loaded from the table are coming through as just "MAIN" TitleType.
    Heres the AfterLoad class:
    public class AfterLoad {
         public static void afterLoadTitle(Descriptor descriptor) {
              ObjectTypeMapping otm = new ObjectTypeMapping();
              otm.setAttributeName("titleType");
              otm.setFieldName("TITLE_TYPE");
              otm.addConversionValue(TitleType.MAIN_TITLE.toString(), TitleType.MAIN_TITLE);
              otm.addConversionValue(TitleType.SUB_TITLE.toString(), TitleType.SUB_TITLE);
              otm.addConversionValue(TitleType.TRANSLATED_TITLE.toString(), TitleType.TRANSLATED_TITLE);
              otm.setDescriptor(descriptor);
              descriptor.addMapping(otm);
    }Any idea why?
    Regards,
    Anthony

  • Extending typesafe enum

    Hello,
    I know that this topic is already cleared that not possible to extend typesafe enum.
    But I don't have any other solution than doing this.
    Here is my problem.
    I have 2 package.
    - package generated
    - package design
    The purpose of the programs is to wrapping package generated in package design, that the user of this program should not use even the smallest part of the package generated.
    package generated contains class A, B, and enum Type
    Here are the declarations:
    File: generated/Type.java
    package generated;
    package generated;
    enum Type
    read, write, readwrite;
    }File: generated/B.java
    package generated;
    public class B
    int num;
    void setNum(int num){this.num = num;}
    int getNum(){ return num;}
    }File: generated/A.java
    package generated;
    public Class A
    int num;
    Type type;
    B b;
    void setNum(int num){this.num = num;}
    int getNum(){ return num;}
    void setType(Type type){this.type = type;}
    Type getType(){ return type;}
    void setB(B b){this.b = b;}
    B getB(){ return b;}
    }Now inside package design:
    File: design/B.java
    package design;
    public class B
    extends generated.B
    }File: design/A.java
    package design;
    public Class A
    extends generated.A
    }Here is the problem:
    File: App.java
    import design.*;
    class App{
    public static void main(String args[])
      A a = new A();
    B b = new B();
    a.setB(b);
    //This part is not expected, while it's using the type of package generated
    //a.setType( generated.Type.write);
    }The problem here is by setting the type of class A. While the method setType of design.A is inherited from generated.A, I cannot setting the value of this type without using the Type from the package generated, even when I add a enum of Type in package design, it still doesn't work, while there couldn't be casted from design.Type to generated.Type.
    This problem is not arised with setB(), while design.B is the subclass of generated.B, and thus can be casted automatically.
    So I have no Idea how can I solve this thing.
    As a note, the package generated cannot be changed.
    If there are anybody have ever faced the same problem, maybe can share their experience.
    Thanks a lot in advance.
    Best regards,
    Heru

    Hi,
    thanks for the reply.
    I'm actually making an API of a data source using JAXB to generate Java Code from an XML schema.
    This generated package is going to have features added along the time. So the wrapper I make is to assure that the API still work when new functions/features added. If I don't create any Wrapper, my written code (extension of the generated code) would be replaced by the new generated code each time the new features added.
    The reason I restrict the user to access the generated package, is because I don't want to confuse the user to access around the generated package and the wrapper package. The purpose of this wrapper is to completely wrapping whole the function of the generated code.
    Hopefully my explanation is understandable.. :-)
    Do you have any other advice how to accomplish this?
    Thanks.
    Best regards,
    Heru

  • Typesafe enums with private access - strange or useful?

    Given the class listed at the bottom, you'll notice that it's possible to specify a typesafe enum, and restrict that enum to clients in such a way that - and here's the strange part - the constant class is not exported in the api, despite the fact that it's required as an argument to the constructor.
    In other words you can legally state:
    MyClass myClass = new MyClass(MyClass.PLAIN);but not:
    MyClass.Constant constant = MyClass.PLAIN;
    MyClass myClass = new MyClass(constant);Anyone else noticed this? (Still coming to terms with the meaning of it).
    /k1
    Example code:
    * Type safety demo
    package blah;
    * Demo class showing the use of inaccessible constants
    public class MyClass {
         /** My first constant */
         public static final Constant FIRST;
         /** My second constant */
         public static final Constant SECOND;
         /* The instance constant field */
         private Constant constant;
         /* static initialiser for the constants */
         static {
              FIRST = new Constant("First");
              FANCY = new Constant("Second");
          * @param constant The constant spec
         public MyClass(Constant constant) {
              super();
              this.constant = constant;
         private static class Constant {
              private String name;
               * @param name The name of my constant
              public Constant(String name) {
                   this.name = name;
    }

    And indeed outside the package...
    package blah.test;
    import blah.*;
    public class Driver {
          * Main method for the sake of demonstration...
         public static void main(String[] args) {
              Object[] constants = MyClass.VALUES;
              for (int i = 0; i < constants.length; i++) {
                   System.out.println(constants);
                   MyClass myClass = new MyClass(constants[i]);
                   System.out.println(myClass);
    ...then...
    * Type safety demo
    package blah;
    * Demo class showing the use of inaccessible constants
    public class MyClass {
         /** My first constant */
         public static final Constant FIRST = new Constant("First");
         /** My second constant */
         public static final Constant SECOND = new Constant("Second");
         /** An array of the constants */
         public static final Constant[] VALUES = { FIRST, SECOND };
         /* The instance constant field */
         private Constant constant;
          * @param constant The constant spec
         public MyClass(Object constant) {
              super();
              if (constant instanceof Constant) {
                   this.constant = (Constant)constant;
         private static class Constant {
              private String name;
               * @param name The name of my constant
              public Constant(String name) {
                   this.name = name;
               * @return The name of the constant
              public String toString() {
                   return name;

  • How to search for a particular pattern in a string

    Hi,

    Hi ,
    How to search for a particular pattern in a string?
    I heard about java.util.regex; and used it in my jsp program.
    Program I used:
    <% page import="java.util.regex"%>
    <% boolean b=Pattern.matches("hello world","hello");
    out.println(b);%>
    I run this program using netbeans and am getting the following error message.
    "Cannot find the symbol : class regex"
    "Cannot find the symbol : variable Pattern "
    How to correct the error?

  • Translation Pattern for a Route Pattern

    I´m trying to make a translation pattern for a route pattern to add a * or a # in the end of the number I'm dialing for example the route pattern is 9.0414XXXXXXX and I want to change to XXXXXXX*. If I dial 904141309131 I see in the phone 4130913*. It seem to be taking a 4 that belong to the 0414 and it is eliminating the las number that in this example is 1. To me the number that I must see when the translation is made is 1309131* and not 4130913*. Is this the way it shoul be done?

    Martin,
    Did you ever find out how to do this ? I have the same requirement and have tried various transform masks none of which has succeeded.
    Thanks in Advance.
    Mark.

  • Suggest good book for J2EE Design Pattern.

    Is there any good book for J2EE Design pattern? I know Head First Design Pattern book, but is focuses oncore java. I want to learn in detail with examples J2EE design pattern.
    Please suggest good books.
    Thanks in advance.
    Rahul.

    most j2ee patterns are discredited now. they were mostly workarounds for deficiencies in ejb 1 & 2 specs.
    "core j2ee patterns" is your best bet, but take it with a grain of salt.
    better to learn spring, IMO:
    springframework.org
    %

  • Code for singleton design pattern

    Hi,
    This is kalyan. Can u provide code for Singleton design pattern.
    Thanks in Advance

    public class Singleton {
      private Singleton() {
      private static Singleton instance;
      public Singleton getSingleton() {
        if (instance == null) instance = net Singleton();
        return instance;
    }Does it make sense?

  • Can I use differnet patterns for a "digital pattern match start trigger"

    Hello,
    Currently I would like use different patterns for a trigger the PCIe-6537 board to start capture data, for example, two patterns: 1101 and 1100 in digital IO lines line0:3, whenever one of this two pattern happens, start capture.
    It seems like "digital pattern match" in DAQmx trigger can use one pattern only.
    thanks!

    Hi tt_ni,
    Pattern I/O only allows the acquisition
    based off of one pattern. This is a “limitation” of the hardware based on the
    registers being set a certain way and monitoring a change from that. You could
    add external circuitry to OR your patterns and based the pattern I/O off of the
    output of that external circuitry. The other option is to look at an FPGA
    option.
    Mark E.
    Precision DC Product Support Engineer
    National Instruments
    Digital Multimeters (DMMs) and LCR Meters
    Programmable Power Supplies and Source Measure Units

  • Newbie Q: PersistenceDelegate for StyledDocument

    Does anyone know of any implementations of a PersistenceDelegate for StyledDocument or DefaultStyledDocument. I tried making one of my own, but I ran into the problem that the Document heirarchy is not very Bean compliant so I can't even get the text to save, much less the formatting. I tried using the EditorKit output, but I think I'm too in experienced w/ PersistenceDelegates to write one that uses EditorKits to read to the documents because the XMLEncoder keeps rejecting everything I try.

    Ya that is the way it works. Everything shows up under music even if you are loading a bunch of different playlists. You can go into Music -> Playlists and then play which ever playlist you want, but you still get a "Master List" of everything on the iPod from the main Music menu item.
    Patrick

  • Typesafe Enums

    I do not use J2SE 5.0, and I need to use an enumerator-like construct. My original code was:
    // Constants to be used with runnersOnBase
    public static final short RUNNER_ON_FIRST = 1;
    public static final short RUNNER_ON_SECOND = 2;
    public static final short RUNNER_ON_THIRD = 4;Obviously this is not a great practice, so I decided to try typesafe enums, which are explained here: http://java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums
    The problem I'm having comes from the fact that, in my program, I can add the integer constants together. Is there a similar way to do that with typesafe enums, and if so, how should the enum class be set up? Thanks a lot. Take care.

    The problem I'm having comes from the fact that, in
    my program, I can add the integer constants together.
    Is there a similar way to do that with typesafe
    enums, and if so, how should the enum class be set
    up? Thanks a lot. Take care.Something like
    public class Enum {
    private static Map enums;
    public static Enum A = new Enum();
    public static Enum B = new Enum();
    public static Enum C = new Enum();
    static {
       enums.add( Integer.valueOf( 0 ), A );
       enums.add( Integer.valueOf( 0 ), B );
       enums.add( Integer.valueOf( 0 ), C );
    public static Enum add( Enum a, Enum b ) {
       int av = enums.get( a );
       int bv = enums.get( b );
       Enum value = enums.get( Integer.valueOf( av + bv ) );
    //   if( value == null  ) throw some exception maybe?
       return value;
    }maybe?

Maybe you are looking for

  • How to change header and footer in login page in oracle apps r12

    Hi all, how to change header and footer in login page in oracle apps r12 and login button background color, please help me thanks saran

  • TS2972 is it possible to use home sharing between two users on the same computer?

    My wife and I have itunes accounts and want to be able to share music we have each bought on our accounts. We have tried setting up the home sharing on our PC but it doesn't show up on the screen. Can anyone please help?

  • Want to use xrandr, but it says extension "RANDR" is missing

    hello! i have a problem and i don't know why, i think i have everything done to be able to use xrandr (nvidia-settings needs it). but i can't. that is my problem: $ xrandr Xlib: extension "RANDR" missing on display ":0.0". RandR extension is missing

  • My HDD is full...but i dont know why

    I just got this T400 less than a month ago and already the HDD is full, but i dont know what its full with. Everything thats installed now either came with the laptop, or isn't big enough to fill up a 140 gig hard drive. The amount of free space seem

  • Preference path missing

    Hi Friends, Although I could successfully install Oracle Portal 3.0 on Oracle9iAS (ver. 9.0.1) with repository in Oracle8i (ver. 8.1.7), I am unable to access the Oracle Portal Home Page fully using the URL : http://<machine_name>:port/pls/portal30.