Android使用枚举正确姿态

作者: WilsonMing | 来源:发表于2017-06-19 17:06 被阅读329次

那实际开发中肯定是要用Java枚举的,那有没有什么解决办法了。答案肯定是有的,只是换成另外一种方式

/**
* Android枚举
*/
public class TestEnum {
  /**
   * @Retention(RetentionPolicy.SOURCE) 注解可以告知编译器不将枚举的注解数据存储在 .class 文件中
   *
   */
  /**
   * @StringDef创建整型和字符串集的枚举注解来验证其他类型的代码引用
   * 具体详细看官网{@link https://developer.android.com/studio/write/annotations.html?hl=zh-cn#adding-annotations}
   */
  @Retention(RetentionPolicy.SOURCE)
  @StringDef({
          POWER_SERVICE,
          WINDOW_SERVICE,
          LAYOUT_INFLATER_SERVICE
  })
  //@interface这是Java用来定义一个注解类。
  public @interface ServiceName {}
  public static final String POWER_SERVICE = "power";
  public static final String WINDOW_SERVICE = "window";
  public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
  public static String getSystemService(@ServiceName String name) {
      if (POWER_SERVICE.equals(name)) {
          return POWER_SERVICE;
      } else if (WINDOW_SERVICE.equals(name)) {
          return WINDOW_SERVICE;
      } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
          return LAYOUT_INFLATER_SERVICE;
      }
      return null;
  }
  public static void main(String[] args) {
      //使用
System.out.println(TestEnum.getSystemService(TestEnum.LAYOUT_INFLATER_SERVICE));
  }
}

这就是官网的写法了。可是发现每次传参数是

TestEnum.LAYOUT_INFLATER_SERVICE
或者
TestEnum.POWER_SERVICE

而不是像我们Java枚举的传参方式

ServiceName.LAYOUT_INFLATER_SERVICE

那是不是需要改造下。查看资料可以这样写

/**
 * Android枚举
 */
public class TestEnum {
    /**
     * @Retention(RetentionPolicy.SOURCE) 注解可以告知编译器不将枚举的注解数据存储在 .class 文件中
     *
     */
    /**
     * @StringDef创建整型和字符串集的枚举注解来验证其他类型的代码引用 具体详细看官网{@link https://developer.android.com/studio/write/annotations.html?hl=zh-cn#adding-annotations}
     */
    @Retention(RetentionPolicy.SOURCE)
    @StringDef({
            ServiceName.POWER_SERVICE,
            ServiceName.WINDOW_SERVICE,
            ServiceName.LAYOUT_INFLATER_SERVICE
    })
    //@interface这是Java用来定义一个注解类。
    public @interface ServiceName {
        String POWER_SERVICE = "power";
        String WINDOW_SERVICE = "window";
        String LAYOUT_INFLATER_SERVICE = "layout_inflater";
    }

    public static String getSystemService(@ServiceName String name) {
        if (ServiceName.POWER_SERVICE.equals(name)) {
            return ServiceName.POWER_SERVICE;
        } else if (ServiceName.WINDOW_SERVICE.equals(name)) {
            return ServiceName.WINDOW_SERVICE;
        } else if (ServiceName.LAYOUT_INFLATER_SERVICE.equals(name)) {
            return ServiceName.LAYOUT_INFLATER_SERVICE;
        }
        return null;
    }

    public static void main(String[] args) {
        //使用
        System.out.println(TestEnum.getSystemService(ServiceName.LAYOUT_INFLATER_SERVICE));
    }
}

不错,就是把常量放到里面去了。这个时候差不多好了,不过怎么看

public static String getSystemService(@ServiceName String name) {
        if (ServiceName.POWER_SERVICE.equals(name)) {
            return ServiceName.POWER_SERVICE;
        } else if (ServiceName.WINDOW_SERVICE.equals(name)) {
            return ServiceName.WINDOW_SERVICE;
        } else if (ServiceName.LAYOUT_INFLATER_SERVICE.equals(name)) {
            return ServiceName.LAYOUT_INFLATER_SERVICE;
        }
        return null;
    }

这个代码还是有点怪怪的,每次添加一个值都需要加一个else if太麻烦了。在Java中可以通过enum.values()获取所有enum的值那是不是有类似的方法,找了资料好像没有发现,那只能通过反射获取所有的public的参数和参数值了

public static String getSystemService(@ServiceName String name) {
        Field[] fields = ServiceName.class.getDeclaredFields();
        for (Field field : fields) {
            //在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象
            field.setAccessible(true);
            String value = null;
            try {
                value = String.valueOf(field.get(field.getName()));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            if (value != null && value.equals(name)) {
                return value;
            }
        }
        return null;
    }

ok完成,代码地址

这里有几个知识点参考资料链接

相关文章

  • Android使用枚举正确姿态

    大家应该都知道Android建议不要用Java枚举,它占用内存很大图片 那实际开发中肯定是要用Java枚举的,那有...

  • Android小经验

    你应该知道的那些Android小经验 1.枚举提供类型安全 Android代码替代枚举的正确之道 2.匿名toke...

  • ios高效开发-正确的使用枚举(Enum)

    ios高效开发-正确的使用枚举(Enum)

  • 枚举 学习笔记

    android 中 我们通常推荐使用 @IntDef 等 代替使用 枚举,很多同学有疑问,为什么抛弃 枚举。我们现...

  • Android 尽量避免使用Enum

    Android之使用枚举利弊及替代方案 知识点: 概述 为什么要使用枚举? 使用 Enum 的缺点 解决方案 总结...

  • 如何正确使用枚举

    枚举类型,对程序员来说再熟悉不过了,但是,你确定你在正确得使用它吗? 在用枚举之前,让我们来区分一下状态和选项这两...

  • Android 性能优化

    一. 内存优化 Android 垃圾回收与内存优化 不要过度使用枚举,枚举占用的内存空间要比整型大。 适度使用静态...

  • Android代码替代枚举的正确之道

    众所周知,在Android官方的性能优化相关课程中曾经提到使用枚举存在的性能问题,不建议在Android代码中使用...

  • Android中使用枚举

    首先我先上一幅图,强行引起大家的共鸣 这是一段很常见的使用if来判断逻辑的代码,但是如果判断的时候写错了一个字符那...

  • 还在用枚举?我早就抛弃了!(Android 注解详解)

    还在用枚举?我早就抛弃了!(Android 注解详解) 前言:使用Support Annotations注解优化代...

网友评论

    本文标题:Android使用枚举正确姿态

    本文链接:https://www.haomeiwen.com/subject/ntfnqxtx.html