在Android中,由于性能问题,建议不要使用枚举。直到最近才如此,直到在Google IO 2018中宣布,枚举现在可以安全使用,尽管对于性能更高的应用程序仍然建议避免使用枚举。
我的问题是:
我们可以在android中广泛使用kotlin密封类吗?
密封类似乎是枚举的扩展。如果是这样,我们应该使用类似于枚举的密封类吗?
谢谢。
答案 0 :(得分:2)
密封类的性能影响与其他任何类相同。如果创建扩展密封类的类的实例,则它将是新实例,因此需要对其进行垃圾收集。如果您有一个object
扩展了一个密封的类,它将是一个单例并且不需要收集(就像枚举常量一样。)。
答案 1 :(得分:1)
在Android上远离enum
的建议被夸大了。对于Android API,避免枚举是有意义的:它们大量使用特殊常量,其中很多对象都存在于应用程序中,并且它们对性能至关重要。
您的自定义应用程序代码可能只想使用几个枚举来表示业务逻辑中的实体。创建十几个,甚至几百个enum
实例将留下难以察觉的足迹。
相同的建议也适用于密封类:一定要使用它们并提高代码质量。仅当您计划着手构建带有成千上万个枚举式常量和类的100 KLOC应用程序时,才停止考虑您的选择。
答案 2 :(得分:0)
垃圾收集
在幕后,枚举是类的静态成员,因此不会收集垃圾。它们会在您的应用程序的生命周期内保留在内存中。这可能是一个好消息或一个坏消息。
就CPU使用率而言,垃圾回收过程非常昂贵。对于对象创建也是如此,您不想一次又一次地创建相同的对象。因此,使用枚举可以节省垃圾收集和对象创建的成本。这就是好处。
缺点是,即使不使用枚举,枚举也会保留在内存中,这可以使内存始终处于占用状态。
要考虑的因素
如果您的应用中有100到200个枚举,则无需担心所有这些。但是,如果您拥有的资源不止于此,则可以决定是否要使用枚举,具体取决于诸如枚举数,枚举数是否一直使用以及分配给JVM的内存量之类的事实。
比较
在when
表达式中,枚举值的比较更快,因为在幕后它使用tableswitch
来比较对象。
Android
在Android中,启用优化后,Proguard会将没有函数和属性的枚举转换为整数。这样,您可以在编译时获得枚举的类型安全性,并在运行时获得整数的性能!
垃圾收集
密封类只是常规类,唯一的例外是它们需要在同一文件中扩展。因此,它们的性能相当于常规类。
密封类的子类型的对象像常规类的对象一样被垃圾收集。因此,您必须承担垃圾收集和对象创建的成本。
要考虑的因素
当内存不足时,如果需要数千个对象,则可以考虑使用密封类而不是枚举。因为垃圾收集器可以在内存不足并且不使用对象时收集对象。
如果使用object
声明来扩展密封类,则这些对象将作为单例对象而不会被垃圾回收,此行为类似于枚举。但是,由于object
声明具有与幕后的对象同名的关联类,因此加载关联的类并将它们保留在内存中会产生额外的开销。
比较
密封类的类型比较在when
表达式中比较慢,因为在幕后它使用instanceof
来比较类型。但是,在这种情况下,枚举和密封类之间的速度差异很小。仅当您在循环中比较数千个常量时,它才重要。
Android
Proguard没有任何整数优化,如密封类的枚举。因此,如果您只想在Android中拥有不带函数和属性的常量,那么最好使用枚举。
就是这样!希望有帮助。