-1

I have some cowboy code that needs a little refinement. I'd like to improve documentational logging without the shame of a huge hard-coded switch statement.

In the following code, I'd like to be able to call a utility, pass it an interface and a value and have it return the name of the field that is initialized to that value. So, if an interface has public static int ONE = 1, then the return value of (T,1) should be "ONE". Like this:

public interface SOBConstants
{
    public static final int EVENT_WILLIE      = 0;
    public static final int EVENT_LOPEZ       = 1;
    public static final int EVENT_GETS_HIS    = 2;
    public static final int EVENT_DUE         = 3;
}

public class Mordecai implements SOBConstants
{
    public void handleEvent(int eventid )
    {
        // Existing log entry:
        log.debug("Handling event" + id );

        // New log entry:
        log.debug("Handling event " + Utils.eventName( SOBConstants, eventid );
        // Should output "Handling event EVENT_WILLIE", etc.

        switch( eventid )
        {
            case EVENT_WILLIE :
                super.attachVictim();
                break;
            case EVENT_LOPEZ :
                super.confirmVictim();
                break;
            case EVENT_GETS_HIS :
                super.openStreetFader();
                break;
            case EVENT_DUE :
                super.animateDescent();
                super.playOutro();
                break;
            default :
                super.detachAndContinueSearch();
        }
        return;
    }
}

public class Utils
{
    public static String eventName(Object container, int eventID)
    {
        String s = "";

        if( container != null )
        {
            Field[] flist = container.getClass().getDeclaredFields();
            for (Field f : flist )
                if( f.getType() == int.class )
                    try {
                        if( f.getInt(null) == eventID ) {
                            s = f.getName();
                            break;
                        }
                    } catch (IllegalArgumentException e) {
                    } catch (IllegalAccessException e) {
                    }
        }
        return s;
    }
}

How can I write (or call) Utils.eventName to allow any interface to be passed and scanned for the field name whose value is also passed? I'd like to focus on the interface rather than passing the implementing class, because that would require some additional discriminator to be added. Currently, the field list is empty either way.

Or is this OK as-is and I just need to call like

Utils.getName(new SOBConstants(){}, 3 );

Also note: I considered using actual enums but this seems like an OK time/effort interim improvement (there are 100's of constants). So DON'T suggest enums. Not relevant.

Thanks! HS

4

1 回答 1

1

使用枚举。

public enum SOBConstants
{
  EVENT_WILLIE (0),
  EVENT_LOPEZ (1),
  EVENT_GETS_HIS (2),
  EVENT_DUE (3);

  private int value;
  private SOBConstants(int value) { this.value = value; }

  public int getValue() {
    return value;
  }

  public MyReturnType doSomething(Object arg) {
    // do new functionality
  }
}

然后,您可以将所需的任何方法添加到枚举中,以获得所需的任何相关功能。

于 2013-04-26T16:22:11.323 回答