Android/Java: get static member variable (static final) name by value

问题描述

在Android/Java开发中,经常会遇到一些类中常量是以int型的静态成员变量声明的,比如Android中的ImageFormat类中

public static final int NV21 = 0x11;
public static final int YUY2 = 0x14;
public static final int JPEG = 0x100;

各种图片格式就是以static final int定义的。而在开发时,不同的图片格式就是值不同的int型变量。但在调试时我们有时候希望知道这个int值具体代表的图片格式,如NV21JPEG等;一般我们会打印出这个int值,然后从代码或参考文档中手动通过值去找到变量名,有没有一种更便捷的方法呢?

解决方法

思路

借助Java的反射机制,可以轻松实现这个功能。

通过指定需要查找的类,以及变量的值,遍历此类中的所有static final静态成员变量,找到值相等的静态成员变量,返回其名字即可。

实现

先上代码

public static String getVariableNameByValue(Class mClass, Object value) throws IllegalAccessException {
    final int PATTERN_FINAL_STATIC = Modifier.FINAL | Modifier.STATIC;
    for (Field field : mClass.getDeclaredFields()) {
        if ((~field.getModifiers() & PATTERN_FINAL_STATIC) == 0) {
            if (field.get(mClass).equals(value)) {
                return field.getName();
            }
        }
    }
    return null;
}

getVariableNameByValue()需要两个参数,mClass即查找的类,value即变量值。

PATTERN_FINAL_STATIC即遍历成员变量的类型,这里指定为static final;然后遍历类中所有的声明getDeclaredFields(),对于每个field首先确认满足PATTERN条件,然后通过get()得到遍历的变量的值,通过equals()与传入的变量值比较,如果相同则getName()返回此变量名。

示例

比如现在有一个ImageFormat

public class ImageFormat {
    public static final int UNKNOWN = 0;
    public static final int RGB_565 = 4;
    public static final int YV12 = 0x32315659;
    public static final int Y8 = 0x20203859;
    public static final int Y16 = 0x20363159;
    public static final int NV16 = 0x10;
    public static final int NV21 = 0x11;
    public static final int YUY2 = 0x14;
    public static final int JPEG = 0x100;
    public static final int YUV_420_888 = 0x23;

    public static int get_YV12() {
        return YV12;
    }

    public static int get_NV16() {
        return NV16;
    }
}

现在

public static void main(String[] args) {
    int yv12 = ImageFormat.get_YV12();
    try {
        String name = getVariableNameByValue(ImageFormat.class, yv12);
        if (name == null) {
            System.out.println("variable's name not found");
        } else {
            System.out.println("variable " + yv12 + " 's name is " + name);
        }
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
}

通过get_YV12()ImageFormat获取到了YV21类型的int值,通过getVariableNameByValue()就可以从这个int值反向得到变量名了。

输出

variable 842094169 's name is YV12

参考