java 枚举类型enum ppt,java中的枚举类型——Enum

本文探讨了在Java编程中使用静态常量与Enum的区别,强调了Enum在类型安全、代码可读性方面的优势。通过Android-Universal-Image-Loader项目的例子,展示了Enum如何方便地处理协议判断。同时,文章提醒开发者注意在Android开发中慎用Enum,因为早期可能存在额外的编译开销,尽管这一问题在后期可能已得到缓解。
摘要由CSDN通过智能技术生成

日常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?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值