2025年5月18日 星期日 乙巳(蛇)年 二月廿 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Java

Java通过反射获取指定类型的变量

时间:02-05来源:作者:点击数:67

Java版本实现

在系统API中,通常会定义一些int类型的静态变量,用于表示一些类型,而我们得到一个int值时,我想知道这个值对应的是哪个类型,就需要拿这个值去静态变量那里比较,很是麻烦,所以就想通过反射得到所有的静态变量,然后用代码帮我找出那个对应的变量名,示例如下:

  • public class MediaType {
  • public static int MP3 = 0x2348;
  • public static int MP4 = 0x2315;
  • public static int AVI = 0x4356;
  • }

如上代码,定义了一些多媒体类型,然后我们通过API获取到了一个具体的类型,如下:

  • int type = mPlayer.getFileMediaType(file);

如上代码,我们得到了一个文件类型,但是它是int类型,需要去Type中对比才能知道它具体是哪一个类型,这就很麻烦了,如果Type 中定义的变量非常多,找起来就麻烦了,而且他是用16进制写的,但是我们拿到的type肯定是十进制的,还要转换为16进制,再去Type中对比查找,虽然可以使用搜索功能,但还是挺麻烦的,所以想要使用代码来帮我们找出这个type值对应的属性名称。

关键代码:

  • Modifier.isPublic(field.getModifiers()) 判断是否是public
  • Modifier.isStatic(field.getModifiers()) 判断是否是static
  • field.getGenericType() 获取变量类型

实现代码如下:

  • public class MediaType {
  • public static int MP3 = 0x2348;
  • public static int MP4 = 0x2315;
  • public static int AVI = 0x4356;
  • }
  • public class Test {
  • public static void main(String[] args) {
  • Map<Integer, String> fieldMap = getAllPublicStaticIntField(MediaType.class);
  • for (Map.Entry<Integer, String> entry : fieldMap.entrySet()) {
  • System.out.println(entry.getKey() + " : " + entry.getValue());
  • }
  • }
  • public static Map<Integer, String> getAllPublicStaticIntField(Class<?> clazz) {
  • Map<Integer, String> fieldsMap = new HashMap<>();
  • try {
  • Field[] fields = clazz.getFields();
  • for (Field field : fields) {
  • int modifiers = field.getModifiers();
  • boolean isPublic = Modifier.isPublic(modifiers);
  • boolean isStatic = Modifier.isStatic(modifiers);
  • boolean isInt = field.getGenericType() == int.class;
  • if (isPublic && isStatic && isInt) {
  • fieldsMap.put((Integer) field.get(null), field.getName());
  • }
  • }
  • } catch (Exception e) {
  • e.printStackTrace();
  • }
  • return fieldsMap;
  • }
  • }

输出结果如下:

  • 8981 : MP4
  • 17238 : AVI
  • 9032 : MP3

OK,三个静态变量都拿到了,当我们得到一个type值为8981,我们不用自己去代码中对比它是哪个类型的值了,直接用代码打印出来即可,如下:

  • public static void main(String[] args) {
  • int type = 8981;
  • String fieldName = getAllPublicStaticIntField(MediaType.class).get(type);
  • System.out.println(type + " is " + fieldName);
  • }

输出如下:

  • 8981 is MP4

注:我发现一个Bug,当我把变量的值设置为0时,则只能获取到一个变量,示例如下:

  • public class MediaType {
  • public static int MP3 = 0;
  • public static int MP4 = 0;
  • public static int AVI = 0;
  • }
  • public class Test {
  • public static void main(String[] args) {
  • Map<Integer, String> fieldMap = getAllPublicStaticIntField(MediaType.class);
  • for (Map.Entry<Integer, String> entry : fieldMap.entrySet()) {
  • System.out.println(entry.getKey() + " : " + entry.getValue());
  • }
  • }
  • public static Map<Integer, String> getAllPublicStaticIntField(Class<?> clazz) {
  • Map<Integer, String> fieldsMap = new HashMap<>();
  • ...
  • return fieldsMap;
  • }
  • }

输出如下:

  • 0 : AVI

不知道这是不是系统bug,如果不是系统bug而是因为我的水平有限无法理解这个异常,请知道原因的朋友告诉我一下这是怎么回事。

后续:大意了,发现原因了,这属于java基础的问题,因为三个变量都是0的话,存到map集合中时,key都是0就重复了,当key是一样时,则后面存进来的会把前面的覆盖,所以最终只保存到了一个变量。

Kotlin版本实现

  • object ReflectUtil {
  • /** 获取指定类中的所有public static int类型的变量 */
  • fun getAllPublicStaticIntField(clazz: Class<*>): Map<Int, String> {
  • val fieldsMap: MutableMap<Int, String> = HashMap()
  • clazz.fields.filter {
  • Modifier.isPublic(it.modifiers) && Modifier.isStatic(it.modifiers) && it.genericType === Int::class.javaPrimitiveType
  • }.forEach {
  • fieldsMap[it.get(null) as Int] = it.name
  • }
  • return fieldsMap
  • }
  • /** 返回指定的值对应的是指定类的哪个变量,如果没有对应的变量,则返回value自身 */
  • fun getPublicStaticIntFieldNameByValue(clazz: Class<*>, value: Int): String {
  • return getAllPublicStaticIntField(clazz)[value] ?: value.toString()
  • }
  • }
  • fun main() {
  • println(ReflectUtil.getPublicStaticIntFieldNameByValue(MediaType::class.java, 8981))
  • }

Kotlin就是爽啊,这代码写起来就是比Java舒服!

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门