【问题标题】:Converting from static class members to text values从静态类成员转换为文本值
【发布时间】:2019-06-11 09:51:49
【问题描述】:

我正在制作一个具有条形码扫描功能的 Android 应用,当我得到结果时,它会作为 Barcode 类的实例返回。对于这个问题,它有两个我感兴趣的值:barcode.formatbarcode.valueFormat

这两个值都是整数,据我所知,这些整数与 Barcode 类定义中基本上是(但不是)作为静态字段的枚举相匹配。

因此,为了便于说明,您已经获得了 Barcode 的类定义,如下所示:

public class Barcode extends AbstractSafeParcelable {
    ...
    public static final int ALL_FORMATS = 0;
    public static final int CODE_128 = 1;
    public static final int CODE_39 = 2;
    public static final int CODE_93 = 4;
    public static final int CODABAR = 8;
    public static final int DATA_MATRIX = 16;
    public static final int EAN_13 = 32;
    public static final int EAN_8 = 64;
    public static final int ITF = 128;
    public static final int QR_CODE = 256;
    public static final int UPC_A = 512;
    public static final int UPC_E = 1024;
    public static final int PDF417 = 2048;
    public static final int AZTEC = 4096;
    public static final int CONTACT_INFO = 1;
    public static final int EMAIL = 2;
    public static final int ISBN = 3;
    public static final int PHONE = 4;
    public static final int PRODUCT = 5;
    public static final int SMS = 6;
    public static final int TEXT = 7;
    public static final int URL = 8;
    public static final int WIFI = 9;
    public static final int GEO = 10;
    public static final int CALENDAR_EVENT = 11;
    public static final int DRIVER_LICENSE = 12;
    ...

barcode 实例可能会返回 32 的 barcode.format 和 5 的 barcode.valueFormat

所以在我的最后,我想要的是让这些数字有一个'EAN_13 : PRODUCT' 的字符串,但乍一看,这些public static final 字段并不容易得到匹配的字符串值。

我当然可以使用此处显示的所有已知类型创建Map<int, string>,但我不喜欢这个想法,因为如果添加任何未来格式,我的Map 将过时。而且我也不喜欢复制已经存在的信息的想法。

那么如何在 Java 中以一种干净、面向未来的方式将这些 int 转换为它们匹配的 String 值?

【问题讨论】:

  • 你为什么不把它们设为枚举值呢?如果你迭代 MyEnum.getValues() (或类似的),如果你添加新值,代码不会改变
  • @Stultuske 我没有参加Barcode 课程
  • 这个类存在于Android中,我只是在消费它。
  • 好的。因此,您需要获取字段列表并对其进行迭代,这样就可以填充您的地图。这可能对此有用:stackoverflow.com/questions/16295949/…
  • 我一直在寻找类似的东西。我接近了一个解决方案,只需使用此处的代码手动制作我的 Mapstackoverflow.com/questions/271109/…

标签: java android


【解决方案1】:

我做了一个小而简单的例子,向您展示如何做到这一点。当然我推荐一些过滤(以防万一,在尝试解析之前确保它是一个 int),但这有点超出了这个 POC 的范围

public class Declared {

    public static final int ONE = 1; // you can add any number of field here
    public static final int TWO = 2; // it should still work. for private fields
                                     // check the api to verify

    public static void main(String[] args) throws Exception {
        // get the fields in the Declared class, currently ONE and TWO
        final Field[] declaredFields = Declared.class.getDeclaredFields();
        Map<String, Integer> fields = new HashMap<>();
        // add it field by field
        for ( Field field : declaredFields ) {
            fields.put(field.getName(), Integer.valueOf(field.getInt(null)));
        }
        // check the entryset for each element in your hashmap. it contains all you need
        final Set<Map.Entry<String, Integer>> entries = fields.entrySet();
        for ( Map.Entry<String, Integer> entry : entries ) {
            System.out.println(entry.getKey() + " - > " + entry.getValue());
        }
    }
}

【讨论】:

  • 这看起来像是在我试图获取字段的类内部实现的。我无法更改该课程,无论在课程之外必须发生什么解决方案。
  • @TKoL 这是在该类中实现的,因为这样更容易以有限代码的形式发布为 POC。它不必在同一个类中。
【解决方案2】:

我意识到这在技术上实际上是不可能的。代码中没有任何内容可以区分应该是barcode.formatbarcode.valueFormat 的值,问题在于存在重叠的值。例如,Barcode.CONTACT_INFOBarcode.CODE_128 都具有 1 的值,因此即使我能够使用反射来创建我的 Map&lt;Integer, String&gt;,映射也只能将这两个值之一设为 1。

我已经实现了如何获取地图:

public static Map<Integer, String> getIntFields(Class clz ) {
    Field[] fields = clz.getFields();
    HashMap<Integer, String> map = new HashMap<Integer, String>();

    for( Field field : fields ) {
        int modifiers = field.getModifiers();
        if (field.getType().equals(int.class) && Modifier.isStatic(field.getModifiers())) {
            String name = field.getName();
            int value = 0;
            try {
                value = field.getInt(null);
            } catch (IllegalAccessException e) {
                continue;
            }

            if (map.containsKey(value)) {
                // do nothing
            } else {
                map.put(value, name);
            }
        }
    }

    return map;
}

后来我才意识到上面的问题。有点烦人的问题,不知道是不是因为 Barcode 类设计不佳,或者它不应该以这种方式使用(可能是后者)。但是我想要的在技术上是不可能的,所以我将只使用 int 值而不是字符串。

【讨论】:

    猜你喜欢
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 2023-03-06
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多