栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

包含2000 + 1枚举常量的枚举类是否达到任何限制?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

包含2000 + 1枚举常量的枚举类是否达到任何限制?

这些类型的问题来自某些初始化程序代码(通常由编译器生成)超过65536字节字节代码的事实。单个方法所包含的字节码不能超过字节数(由于类文件格式的限制)。

像这样的问题的一个常见来源是像这样的大数组:

byte someBytes = { 1, 2, 3, ..., someBigValue };

这里的问题是,此类字段实际上是在生成的初始化程序(构造函数或静态初始化程序)中使用 someBigValue 赋值语句初始化的。

枚举值实际上是以类似的方式初始化的。

给定以下枚举类:

public enum Foo {  ConSTANT(1);  private Foo(int i) {  }}

我们查看的输出,

javap -v
并看到以下代码块:

  static {};    flags: ACC_STATIC    Code:      stack=5, locals=0, args_size=0         0: new#4       // class Foo         3: dup         4: ldc#7       // String ConSTANT         6: iconst_0         7: iconst_1         8: invokespecial #8       // Method "<init>":(Ljava/lang/String;II)V        11: putstatic     #9       // Field CONSTANT:LFoo;        14: iconst_1        15: anewarray     #4       // class Foo        18: dup        19: iconst_0        20: getstatic     #9       // Field CONSTANT:LFoo;        23: aastore        24: putstatic     #1       // Field $VALUES:[LFoo;        27: return

如您所见,有很多字节码操作可以

CONSTANT
使用正确的值进行实例化。如果您有 许多
这样的枚举值,则该静态初始化程序块的大小可能会轻易超过64k字节的代码,从而使该类不可编译。

一种可能的解决方法是通过减少参数的数量(例如,根据枚举值的索引而不是使用参数来计算传入的数量)来减小初始化代码的大小。那可能只是给您足够的摆动空间,以进一步扩展此范围。

另外,您可以尝试通过实现公共接口将枚举拆分为多个枚举。枚举可以按区域/意图/类别/ …进行分组:

public interface MessageType {  int getId();}public enum ConnectionMessage implements MessageType {  INIT_ConNECTION(1),  LOGIN(2),  LOGOUT(3),  CLOSE_ConNECTION(4);  // getId pre, constructor, ...}public enum FrobnicationMessage implements MessageType {  FROBNICATE_FOO(5),  FROBNICATE_BAR(6),  DEFROB_FOO(7),  DEFROB_BAR(8),  ...  // getId pre, constructor, ...}

我假设枚举值实际上是在代码中的某个地方引用的,而不仅仅是纯值持有者,如果它们只保存值,而单个值在您的代码中并未得到不同对待,则将其替换为每个数据项实例化一次的单个类存储在中央资源中可能是最好的方法。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/429033.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号