日常java编程中,常见用一些静态常量表示一些状态码,特殊含义的标志等,例如:

1

2

3

4

5public class A{

public static final int STATUS_SUCCESS = 1;

public static final int STATUS_FAIL = 2;

public static final int STATUS_CANCEL = 3;

}

这样使用,虽然看上去很好,但是有不少隐形的问题:

类型不安全;

必须确保int范围;

如果打印的话,只能看到int的值,查看含义的话,需要人工比对

其实这种情况,java的Enum往往是更好的选择。

现在结合Android开源图片下载项目Android-Universal-Image-Loader,我们来简略分析一下Enum的用法。

Enum的基本使用如下:

1

2

3public Enum Scheme {

HTTP, HTTPS, FILE, CONTENT, ASSETS, DRAWABLE, UNKNOWN;

}

使用Enum后,立竿见影的好处是使用switch很方便:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18public InputStream getStream(String imageUri, Object extra) throws IOException{

switch (Scheme.ofUri(imageUri)) {

case HTTP:

case HTTPS:

return getStreamFromNetwork(imageUri, extra);

case FILE:

return getStreamFromFile(imageUri, extra);

case CONTENT:

return getStreamFromContent(imageUri, extra);

case ASSETS:

return getStreamFromAssets(imageUri, extra);

case DRAWABLE:

return getStreamFromDrawable(imageUri, extra);

case UNKNOWN:

default:

return getStreamFromOtherSource(imageUri, extra);

}

}

而且这个时候,如果把变量的值打印出来的话,会打印Enum的内容,而不是int整型,非常直观:

1

2

3

4

5

6Scheme scheme = Scheme.HTTPS;

System.out.println(s);

/* 输出结果:

* HTTPS

*/

但实际上,Enum的使用方式远非如此简单,Enum就是一个类,可以包含变量,可以包含函数,当然,也有自己的构造函数。

首先,Enum有两个静态方法:

1

2

3

4values()

获取枚举类型的所有枚举常量

valueOf(Class EnumType, String name)

返回带指定名称的指定枚举类型的枚举常量。

使用方法以最原始的Enum举例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16public Enum Scheme {

HTTP, HTTPS, FILE, CONTENT, ASSETS, DRAWABLE, UNKNOWN;

}

for (Scheme scheme : Scheme.values()) {

System.out.print(scheme);

System.out.print(" ");

}

/* 输出结果:

* HTTP HTTPS FILE CONTENT ASSETS DRAWABLE UNKNOWN

*/

System.out.println(Scheme.valueOf(Scheme.class, "HTTP"));

/* 输出结果:

* HTTP

*/

这个时候,我们做一些小小的改动,去为Enum添加一个变量,同时重写toString方法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16public Enum Scheme {

HTTP("http"), HTTPS("https"), FILE("file"), CONTENT("content"),

ASSETS("assets"), DRAWABLE("drawable"), UNKNOWN(

"unknown");

private String scheme;

Scheme(String s) {

scheme = s;

}

@Override

public String toString(){

return scheme;

}

}

这个时候,我们打印一下看看:

1

2

3

4

5

6

7for (Scheme scheme : Scheme.values()) {

System.out.print(scheme);

System.out.print(" ");

}

/* 输出结果:

* http https file content assets drawable unknown

*/

可以看到,我们在Enum中的变量可以被Enum中的方法使用。我就说嘛,枚举就是一个类。

现在,让我们仔细看一下Android-Universal-Image-Loader中的Enum定义:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46public Enum Scheme {

HTTP("http"), HTTPS("https"), FILE("file"), CONTENT("content"),

ASSETS("assets"), DRAWABLE("drawable"), UNKNOWN("");

private String scheme;

private String uriPrefix;

Scheme(String scheme) {

this.scheme = scheme;

uriPrefix = scheme + "://";

}

/**

* Defines scheme of incoming URI

*

* @param uri URI for scheme detection

* @return Scheme of incoming URI

*/

public static Scheme ofUri(String uri){

if (uri != null) {

for (Scheme s : values()) {

if (s.belongsTo(uri)) {

return s;

}

}

}

return UNKNOWN;

}

private boolean belongsTo(String uri){

return uri.toLowerCase(Locale.US).startsWith(uriPrefix);

}

/** Appends scheme to incoming path */

public String wrap(String path){

return uriPrefix + path;

}

/** Removed scheme part ("scheme://") from incoming URI */

public String crop(String uri){

if (!belongsTo(uri)) {

throw new IllegalArgumentException(String.format("URI [%1$s] doesn't have expected scheme [%2$s]", uri, scheme));

}

return uri.substring(uriPrefix.length());

}

}

我们看到,这里面针对协议的Enum,除了定义基本的Enum类型,还提供了根据url去判断是哪一种Enum的静态方法。正因为有这个静态方法,所以,在项目中有了如下优雅的用法:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16switch (Scheme.ofUri(imageUri)) {

case HTTP:

case HTTPS:

return getStreamFromNetwork(imageUri, extra);

case FILE:

return getStreamFromFile(imageUri, extra);

case CONTENT:

return getStreamFromContent(imageUri, extra);

case ASSETS:

return getStreamFromAssets(imageUri, extra);

case DRAWABLE:

return getStreamFromDrawable(imageUri, extra);

case UNKNOWN:

default:

return getStreamFromOtherSource(imageUri, extra);

}

Enum那么厉害,那在我们的Android开发中要注意啥呢?要注意的就是,尽量不用Enum。

为啥???

早期谷歌语焉不详的提出,enum使用在Android中会产生额外编译开销,后来又语焉不详的把在《性能建议》中不建议使用Enum删除了。个人理解,可能早期的编译器,对Enum的编译不友好,毕竟,Android是自己的一套编译器,而不是java那一套,后来不断改进不断改进,这个问题缓和了。但毕竟Android开发还要考虑早期用户,所以,这里,并不建议大量使用Enum在我们的项目中。

关于这点,可以参考:

Why doesn’t Android use more enums?

Why was “Avoid Enums Where You Only Need Ints” removed from Android’s performance tips?

java 枚举类型enum ppt,java中的枚举类型——Enum相关推荐

  1. java接口参数类型为枚举_Spring MVC处理参数中的枚举类型通用实现方法

    前言 在开发的过程中,会涉及到大量的枚举类型数据,我们都知道,Springmvc本身能自动转换很多的数据类型,也支持你自定义转换类型,非常灵活. 本文主要介绍的是关于Spring MVC处理参数的枚举 ...

  2. c++ enum 给定类型_讲解C++中的枚举类型以及声明新类型的方法

    C++枚举类型如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型.所谓"枚举"是指将变量的值一一列举出来,变量的值只能在列举出来的值的范围内.声明枚举类型用 ...

  3. mysql 枚举 enum用法_mysql中的枚举类型ENUM的用法:

    mysql中的枚举类型ENUM的用法: (2010-06-18 13:44:13) mysql中的枚举类型ENUM的用法: mysql中的枚举类型ENUM是一个字符串对象,它的值是自表创建时在列规定中 ...

  4. java鸭子类型_语言设计中的鸭子类型风格

    在动态语言的世界里一直流传着一种叫做鸭子类型的风格,其来自谚语:"如果行鸭子一样走路,像鸭子一样呱呱叫,那它就是一只鸭子". 从鸭子类型,我们可以联想到它的推导,并不在乎类型的真正 ...

  5. java对象与类ppt,JAVA语言对象与类.ppt

    JAVA语言对象与类.ppt 第三章 对象与类,3.1 类与对象 3.2 定义类 3.3 成员变量的作用域 3.4 方法重载 3.5 创建对象 3.6 构造方法 3.7 this关键字 3.8 初始化 ...

  6. java方法的继承 ppt,Java学习之继承基本介绍和实例方法,java学习继承实例

    Java学习之继承基本介绍和实例方法,java学习继承实例 继承基本介绍 继承概念不做过多介绍.这里只介绍继承使用过程中需要注意的地方.继承的基本语法格式如下,用关键字extends来表示继承关系. ...

  7. c语言中指针的类型,学习C语言中的指针类型

    摘要:结合我院学生十年来参加全国计算机等级考试(C语言部分)情况,通过分析成绩分布与题型关系,我们发现指针方面的题型失分率最高.在此基础上结合教学实际,本文提出学习指针知识的方法和顺序过程,并将其应用 ...

  8. 将C#中DateTime类型转化为JavaScript中的Date类型

    将C#中的DateTime类型数据返回到前端页面时,显示的样子如下图所示: 可以用JS前端操作转化成JS的Date格式,直接上代码 : // 对Date的扩展,将 Date 转化为指定格式的Strin ...

  9. android mimetype类型,如何确定android中的MIME类型?

    如何确定android中的MIME类型? 假设我有一个完整的文件路径,如:(/ sdcard / tlogo.png).我想知道它的mime类型. 我为它创建了一个函数public static St ...

最新文章

  1. 【★更新★】高性能 Windows Socket 服务端与客户端组件(HP-Socket v2.0.1 源代码及测试用例下载)...
  2. php获取ip写到文本,php 文本转HTML与获取IP函数
  3. 来学习ansibie(1)
  4. 那些值得思考的PHP问题
  5. 重构(Refactoring)技巧读书笔记 之二
  6. flex学习网站大全(转)
  7. DiskGenius的 “终止位置参数溢出”错误解决方法。
  8. python进程与线程_Python进程与线程知识
  9. Q78:规则网格(Regular Grids)——Ray Tracing中的一种加速技术
  10. 基于VS2015的C#的GDAl环境配置
  11. PollingBlockTracker - encountered an error while attempting to update latest block:
  12. 分享:绘图不可不知的CAD经典技巧
  13. SBUS协议数据演示
  14. python教孩子学编程_学编程要从娃娃抓起——教孩子学Python
  15. Android阿里云推送离线通知集成踩坑之路
  16. Dart | Dart 语言基础知识梳理
  17. SQL中进行去重的方法
  18. H5--drag拖拽事件
  19. 数据库 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\test1.mdf' 已存在。请选择其他数据库
  20. eclipse安装angularjs

热门文章

  1. 吴恩达神经网络和深度学习-学习笔记-37-inception网络
  2. 安卓网络连接全解:包括网络连接状态的监听、网络数据使用状态的监听、获取当前网络连接情况、启动wifi、获取当前连接wifi的网络情况、扫描wifi热点
  3. matlab2c使用c++实现matlab函数系列教程-polyder函数
  4. 设置占用GPU的比例
  5. 杭电 -- 2000
  6. [学习笔记]后缀平衡树
  7. java String 常用方法集合
  8. Java==与equals方法的区别
  9. java事务的类型——面试被问到
  10. linux使用mount命令挂载、umount命令取消挂载