本文由咕咚发布在个人博客,转载请注明出处。

本文永久地址:https://gudong.name/2019/11/04/use-enum-or-not.html


在 Android 官方文档推出性能优化的时候,从一开始有这样一段说明:

Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.

意思是说在 Android 平台上 avoid 使用枚举,因为枚举类比一般的静态常量多占用两倍的空间。

如果你还不了解枚举,参看文章 枚举介绍以及枚举的本质

由于枚举最终的实现原理还是类,在编译完成后,最终为每一种类型生成一个静态对象,而在内存申请方面,对象需要的内存空间远大于普通的静态常量,而且分析枚举对象的成员变量可知,每一个对象中默认都会有一个字符数组空间的申请,计算下来,枚举需要的空间远大于普通的静态变量。具体分析可见这篇文章

所以,照此来看,在 Android 这样对内存寸土必争的平台上,如果只是使用枚举来标记类型,那使用静态常量确实更优,但是现在翻看官方文档发现,这个建议已经被删除了。(

为什么官方会删除?难道是之前的建议有错误吗,或者描述的不够精确?

个人认为,枚举占用空间比普通类型的静态常量大,这是事实,没问题,但是据此就建议不在 Android 中使用时不妥的,具体看 JakeWharton 在 reddit 上的一个评论

The fact that enums are full classes often gets overlooked. They can implement interfaces. They can have methods in the enum class and/or in each constant. And in the cases where you aren't doing that, ProGuard turns them back into ints anyway.

The advice was wrong for application developers then. It's remains wrong now.

最重要的一句是

ProGuard turns them back into ints anyway.

在开启 ProGuard 优化的情况下,枚举会被转为 int 类型,所以内存占用问题是可以忽略的。具体可参看 ProGuard 的优化列表页面 Optimizations Page,其中就列举了 enum 被优化的项,如下所示:

class/unboxing/enum

Simplifies enum types to integer constants, whenever possible.

既然 ProGuard 会把枚举优化为整形,那是不是在 Android 中,就可以继续无所顾忌的使用枚举了呢?

Android 开发中是否应该使用枚举?的更多相关文章

  1. Android开发中常见的设计模式 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Android学习探索之Java 8 在Android 开发中的应用

    前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...

  3. android开发中fragment获取context

    在用到fragment时无法使用.this来指定当前context内容,android开发中fragment获取context,可以使用getActivity().getApplicationCont ...

  4. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  5. Android开发中的输入合法性检验

    Why ? 合法性检查对于程序的健壮性具有重要作用.在Android开发中,良好的合法性检查设计机制可以使程序更加清晰,产生bug更少,交互更加友好. What ? 合法性检查的目的在于确定边界.对于 ...

  6. 在android开发中使用multdex的方法-IT蓝豹为你整理

    Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个,因此在Android开发中,需要使用到MultiDex来解决这个问 ...

  7. 怎样实现了捕获应用中的日志在android开发中

    怎样实现了捕获应用中的日志在android开发中,大家可研究一下. Process mLogcatProc = null; BufferedReader reader = null; try { mL ...

  8. Android开发中Eclispe相关问题及相应解决(持续更新)

    1.Eclipse项目中的Android Private Libraries没有自动生成. 一般而言,在Android开发中,项目中引用到的jar包会放到项目目录中的libs中,引入库会放到Andro ...

  9. Android开发中的问题及相应解决(持续更新)

    最近博客写的少了,以后还得经常更新才行. ------------------------------------------------------------ 1.特定业务需求下try cath ...

随机推荐

  1. springmvc引入静态资源文件

    如果web.xml中配置的DispatcherServlet请求映射为“/”, springmvc将捕获web容器所有的请求,当然也包括对静态资源的请求.springmvc会将他们当成一个普通请求处理 ...

  2. 旧瓶新酒-获取网络资源即爬取下载页面内容(图片、html、css、js等)

    这个java获取网络资源以前也写过不少 最近用到又重新写了一个,apache.commons.io中的例子就非常好,但是无法对请求进行详细设置 于是大部分照搬,局部替换以设置请求头 如需更加复杂的设置 ...

  3. 某CTF平台一道PHP代码审计

    这道题不是说太难,但是思路一定要灵活,灵活的利用源码中给的东西.先看一下源码. 首先要理解大意. 这段源码的大致的意思就是,先将flag的值读取放在$flag里面. 后面再接受你输入的值进行判断(黑名 ...

  4. 基于STM32F429和HAL库的CAN收发例程

    1.CAN协议介绍 CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议.在当前的汽车产业中,出于对安全性.舒适性.方便性.低公 ...

  5. 点云之OpenMesh:error C1083:无法打开包括文件:“OpenMesh/Core/IO/MeshIO.hh”:No such file or directory

    1.这是一个错误引发的惨案:错误提示如下: 在进行点云程序调试时,出现错误:[error C1083:无法打开包括文件:“OpenMesh/Core/IO/MeshIO.hh”:No such fil ...

  6. 第一天 hello world 启程

    #include<stdio.h> int main() { printf(" Hello world"); return 0; }

  7. Mysql多数据库备份

    备份数据脚本 #!/bin/bash # date是linux的一个命令 date [参数] [+格式] time=` date +%Y_%m_%d_%H_%M_%S ` # 备份输出路径 backu ...

  8. mssql数据库提权

    1.关于 “xp_cmdshell” “存储过程”:其实质就是一个“集合”,那么是什么样的结合呢,就是存储在SqlServer中预先定义好的“SQL语句集合”,说的更直白一些就是使用T-SQL语言编写 ...

  9. [Luogu2359] 三素数数

    题目背景 蛟川书院的一道练习题QAQ 题目描述 如果一个数的所有连续三位数字都是大于100的素数,则该数称为三素数数.比如113797是一个6位的三素数数. 输入输出格式 输入格式: 一个整数n(3 ...

  10. c使用二叉链表创建二叉树遇到的一些疑问和思考

    二叉链表存储二叉树 学习的时候参考的是<大话数据结构>,书中是这样定义的 typedef char TElemType; typedef struct BiTNode { TElemTyp ...