枚举真的比静态常量更占空间吗?
前两天在网上看到一条信息:枚举比静态常量更占用空间。
这是真的吗?
前言
枚举
枚举类型是Java 5中新增特性的一部分,它是一种特殊的数据类型,之所以特殊是因为它既是一种类(class)类型却又比类类型多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁性、安全性以及便捷性。
枚举实现原理
在使用关键字enum创建枚举类型并编译后,编译器会为我们生成一个相关的类,这个类继承了Java API中的java.lang.Enum类,也就是说通过关键字enum创建枚举类型在编译后事实上也是一个类类型而且该类继承自java.lang.Enum类。
枚举
新建一个枚举类
package com.example.demo;
/**
* @Author: 少年闰土
* @Date: 2019/12/27 0027 上午 9:23
* @Description:
*/
public enum Season {
SPRING("春天", "趁春踏青"),
SUMMER("夏天", "夏日炎炎"),
AUTUMN("秋天", "秋高气爽"),
WINTER("冬天", "围炉赏雪");
private final String name;
private final String desc;
Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public String getDesc() {
return desc;
}
}
接下来使用javac命令进行编译:生成class文件,然后再通过javap反编译
public final class com.example.demo.Season extends java.lang.Enum<com.example.de
mo.Season> {
public static final com.example.demo.Season SPRING;
public static final com.example.demo.Season SUMMER;
public static final com.example.demo.Season AUTUMN;
public static final com.example.demo.Season WINTER;
//编译器为我们添加的静态的values()方法
public static com.example.demo.Season[] values();
//编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法
public static com.example.demo.Season valueOf(java.lang.String);
//构造方法
public java.lang.String getName();
public java.lang.String getDesc();
static {};
}
静态常量
package com.example.demo;
/**
* @Author: 少年闰土
* @Date: 2019/12/27 0027 上午 10:49
* @Description:
*/
public class Season {
public static final String SPRING ="春天";
public static final String SUMMER ="夏天";
public static final String AUTUMN ="秋天";
public static final String WINTER ="冬天";
}
javap反编译后:
public class com.example.demo.Season {
public static final java.lang.String SPRING;
public static final java.lang.String SUMMER;
public static final java.lang.String AUTUMN;
public static final java.lang.String WINTER;
public com.example.demo.Season();
}
对比
枚举
静态常量
编译后的枚举class文件大小为1471字节,静态常量class文件大小为400字节。
用Chkdsk查看簇大小
经过对比枚举类型文件大小更大一些。
枚举的实现原理就是定义一个类,然后实例化几个由final修饰的这个类的对象,每个实例都带有自己的元信息。而常量相比之下,没有这一层封装,只占用最基本的内存,包括引用,和它的值本身,要简单轻巧很多。如果值可以使用基本类型而不是包装类型,那更不用说了。 不过话又说回来,通常情况下我们没必要在意这种区别。如果用枚举可读性、可扩展性更好,用就是了,枚举占那点内存,沧海一粟。在性能与代码维护性之间,除个别情况,优先选后者。高级编程语言的诞生本身就是硬件提升的背景下,牺牲某些性能来降低开发门槛,提高开发效率的,相对于微小的性能损耗,人力成本更值钱