【问题标题】:How to get field name from Java interface value?如何从 Java 接口值中获取字段名称?
【发布时间】:2013-04-26 16:09:23
【问题描述】:

我有一些需要稍微改进的牛仔代码。我想改进文档日志记录,而不用为巨大的硬编码 switch 语句感到羞耻。

在下面的代码中,我希望能够调用一个实用程序,向它传递一个接口和一个值,并让它返回初始化为该值的字段的名称。所以,如果一个接口有 public static int ONE = 1,那么 (T,1) 的返回值应该是“ONE”。像这样:

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;
    }
}

如何编写(或调用)Utils.eventName 以允许传递任何接口并扫描其值也传递的字段名称?我想专注于接口而不是传递实现类,因为这需要添加一些额外的鉴别器。目前,无论哪种方式,字段列表都是空的。

或者这样可以吗,我只需要像这样打电话

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

另请注意:我考虑过使用实际枚举,但这似乎是一个不错的时间/精力临时改进(有 100 个常量)。所以不要建议使用枚举。不相关。

谢谢! HS

【问题讨论】:

  • 使用枚举会是一个非常更好的主意。将值转换为其字符串表示形式更容易,并且您可以确保正确的事件类型仅用于正确的事件处理程序。我会选择那个解决方案。
  • @Jon - 我完全同意,除了在时间范围内要触及的代码太多,我必须进行这种渐进式改进。

标签: java reflection interface parameters


【解决方案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
  }
}

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

【讨论】:

  • 天哪,虽然,好吧,谢谢,嗯,我已经说过 - 现在 3 次 - 枚举不是解决方案。该任务是读取/解析现有接口,而不是正确重写。
  • 我花了一分钟把你的班级改成我的班级。没你想的那么长,制作enums 很简单。编写解决方法将花费您更长的时间才能正确执行。
  • 好的,就像我说的,“谢谢”,但这是在回答您的问题,而不是我的问题。我想要“如何传递和解析接口”的答案,而不是如何通过重新设计来避免这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多