我有一个问题,我们何时应该使用Enum,何时应该使用最终常量?
我知道它已经在Enums and Constants. Which to use when?进行了讨论,尽管它是C#问题。
我的问题是为什么Android使用这么多常量而不是枚举?例如 , Context
在我看来,如果我们使用常数,可能存在如下风险: 如果我们定义一个LEVEL常量
public static final int LEVEL_LOW=1;
public static final int LEVEL_MEDIUM=2;
public static final int LEVEL_HIGH=3;
当我们传递一个int = 4的参数时。它不会有编译错误,如果我们传递1的数字,代码阅读器可能不容易知道它的意思。
但Enum可以解决这个问题,虽然它可能会导致更多的开销,因为它是Object。
那么为什么Android使用常量而不是Enum? 在这种情况下,我们何时应该使用常数或枚举?
答案 0 :(得分:16)
这与android历史有关。在Froyo之前的版本中存在未经证实的性能问题。建议开发人员不要使用enum。自Froyo以来,设计性能文档按照here所述进行了重写。
正如您可能已经注意到的那样,我们重新编写了“性能设计” Froyo的文档。以前这可能是一堆东西 在某些方面是真实的,但很久以来就不再承担任何责任 与现实的关系。在Froyo中,文档中的每一个声明 以基准为后盾,以证明(或将来反驳)它。您 可以仔细阅读"设计性能"浏览器中的基准测试。
但改变遗留内容的结构毫无意义。
性能可能与需要存储String有关。每个常量与多个枚举的单个类的创建之间存在显着差异。
例如在Java 7中,当你有一个包含两个字段的枚举时,你需要在poll常量中有44个项目,对于一个有两个静态最终整数的类,你只需要17个。
有什么区别
class ContantField {
public static final int f1 = 0;
public static final int f2 = 1;
}
enum ContantEnum {
E1,E2
}
这两个声明在存储和使用方式上有很大不同。 ContantEnum
的简化可能看起来像
class ContantEnum {
public static final Enum enum0 = new Enum("V1",0);
public static final Enum enum1 = new Enum("V2",1);
public static final Enum[] values = new Enum[] {enum0,enum1};
}
通过这种简化,您可以注意到enum
需要的内存资源比int
更多。
要回答您的问题,必须了解枚举的作用。枚举的一个作用是增加编译时类型的安全性。
要指出这一点,请参阅此示例:
public void setImportantThing(int priviledge, int rights)
public void setImportantThing(Privilege p, Right r)
在int
的情况下,我们可以传递任何int值。在他enum
的情况下,我们被迫使用正确的一个。
我们这里的情况是在编译时验证和运行时内存使用之间进行权衡。您应该自己决定何时使用enum
以及static int
足够安全的地方。
注意: enum是在1.5版本的Java中引入的,在它出现问题之前使用它们more。
在Android Studio Beta中,开发人员可以使用注释强制执行类型安全。
答案 1 :(得分:6)
枚举是:
更安全 - 更有弹性。
如果更改错误,更改枚举列表更有可能导致编译时错误。
更清晰 - 大多数开发人员会立即明白项目是以某种方式连接的。
enum { A, B, C }
更明显是一个项连接项而不是psfi A = 0; psfi B = 1; psfi C = 2;
因此,除非您使用public static final int
具有可衡量优势,无论是内存占用还是速度,都应始终使用enum
。
答案 2 :(得分:1)
Android核心基本上是C / C ++代码。这适用于整数。因此,当在Java中使用枚举时,每个值都必须“翻译”。这将花费CPU时间和内存。这两种情况在嵌入式系统中都很少见。
答案 3 :(得分:1)
简单地说Enums使用的资源比公共静态最终字段更多,所以不要在每个字节都很重要的移动编程中使用ENUM。
http://developer.android.com/training/articles/perf-tips.html#UseFinal
答案 4 :(得分:0)
当我亲自编程时,我希望使用上面的方法来表示一个重要的整数。例如,MAX_INT可以映射到int 50.这很有用,因为如果我愿意,我可以将int更改为60,而不必遍历所有代码并将50s更改为60s。
对于枚举,它是(如this link所解释的)特殊数据类型,它使变量成为一组预定义常量。因此,如果您希望有一组受限制的值可供选择,这将是一个理想的选择 - 而您选择的上述样式将是可扩展的,并且如上所述,通过选择不在边界内的值可以轻松利用。