-3

I tested class, enum, interface these 3 ways to encapsulate constant String.

   public class Company {
        public final static String CAPITAL_ONE = "Capital_One";
    }
    public interface ICompany {
        public final static String CAPITAL_ONE = "Capital_One";
    }
    public enum ECompany {
        CAPITAL_ONE
    }

After compile, they generated 330 bytes, 181 bytes and 818 bytes bytecode which means interface ICompany will cost less memory when loaded into jvm. Why is this?

kurryt
  • 210
  • 4
  • 10
  • 3
    Maybe because those are not equivalent data structures? – Boo Radley Jul 27 '16 at 14:43
  • 1
    The interface just needs to have a field name, type, and value. The enum needs to store multiple different method implementations (`values()` and `valueOf(String)`, as well as static initialization) in addition to the constant value. – resueman Jul 27 '16 at 14:48

2 Answers2

3

Use the javap utility to examine the 3 ".class" files and compare the outputs. For example:

$ javap -c Company.class 

The short answer is there are some standard methods (values(), valueOf(String), toString()) that the enum class has to implement, but the other classes don't have to.

Having said that, the size of a ".class" file is not necessarily an accurate predictor of the memory used when a class has been loaded and JIT compiled.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

A single class file defines either a class or interface. Looking at the structure (https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html):

    ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
    }

An Enum is a class, and if you look what it compiles to, you can see why there is necessary overhead (see here: In java, What does such enum type compile to?). An interface is an abstract type, which is really just a set of operations and constants that a class must conform to.

ICompany.class:

����4   
CAPITAL_ONELjava/lang/String;
ConstantValue
SourceFile
ICompany.javaICompanyjava/lang/ObjectCapital_One

ECompany.class:

����4(  


!

"
"   #$CAPITAL_ONE
LECompany;$VALUES[LECompany;values
()[LECompany;CodeLineNumberTablevalueOf(Ljava/lang/String;)LECompany;<init>(Ljava/lang/String;I)V   Signature()V<clinit>Ljava/lang/Enum<LECompany;>;
SourceFile
ECompany.java
%&ECompany'java/lang/Enumclone()Ljava/lang/Object;5(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;@1
@
    "
����    "
*���*+��7�Y��   �Y� S��

From the class files, you can see that the interface in the example does not have much added to it in terms of methods or flags, hence the smaller size.

Community
  • 1
  • 1
kurryt
  • 210
  • 4
  • 10