Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java enum and additional class files

Tags:

java

enums

I've noticed enums introduce many additional class files (Class$1) after compilation bloating the total size. It seems to be attached to every class that even uses an enum, and these are often duplicated.

Why does this occur and is there a way to prevent this without removing the enum.

(Reason for question is space is at a premium for me)

EDIT

On investigating the issue further, Sun's Javac 1.6 creates an additional synthetic class each time you use a switch on an Enum. It uses some kind of SwitchMap. This site has some more information, and here tells you how to analyse what Javac is doing.

An additional physical file seems a high price to pay each time you use a switch on an enum!

Interestingly, Eclipe's compiler does not produce these additional files. I wonder if the only solution is to switch compilers?

like image 493
Pool Avatar asked Dec 02 '09 17:12

Pool


People also ask

Should enum be in a separate file in Java?

An enum is a class and follows same regulations. Having it on its own file is exactly like moving an inner class in a separate file, nothing more nor less. So yes you can move it inside one of the class and be able to access it from outside with OuterClass.

Can enum extend any class Java?

Enum cannot extend any class in java,the reason is, by default Enum extends abstract base class java. lang. Enum. Since java does not support multiple inheritance for classes, Enum can not extend another class.

Can a class have multiple enums?

java file may have only one public class. You can therefore declare only one public enum in a . java file. You may declare any number of package-private enums.

Can you have an enum in a class Java?

Enum Class in Java In Java, enum types are considered to be a special type of class. It was introduced with the release of Java 5. An enum class can include methods and fields just like regular classes. When we create an enum class, the compiler will create instances (objects) of each enum constants.


1 Answers

I was just bit by this behavior and this question showed up when Googling. I thought I'd share the little bit of extra information I found out.

javac 1.5 and 1.6 create an additional synthetic class each time you use a switch on an enum. The class contains a so-called "switch map" which maps enum indices to switch table jump numbers. Importantly, the synthetic class is created for the class in which the switch occurs, not the enum class.

Here's an example of what gets generated:

EnumClass.java

public enum EnumClass { VALUE1, VALUE2, VALUE3 } 

EnumUser.java

public class EnumUser {     public String getName(EnumClass value) {         switch (value) {             case VALUE1: return "value 1";             // No VALUE2 case.             case VALUE3: return "value 3";             default:     return "other";         }     } } 

Synthetic EnumUser$1.class

class EnumUser$1 {     static final int[] $SwitchMap$EnumClass = new int[EnumClass.values().length];      static {         $SwitchMap$EnumClass[EnumClass.VALUE1.ordinal()] = 1;         $SwitchMap$EnumClass[EnumClass.VALUE3.ordinal()] = 2;     }; } 

This switch map is then used to generate an index for a lookupswitch or tableswitch JVM instruction. It converts each enum value into a corresponding index from 1 to [number of switch cases].

EnumUser.class

public java.lang.String getName(EnumClass);   Code:    0:   getstatic       #2; //Field EnumUser$1.$SwitchMap$EnumClass:[I    3:   aload_1    4:   invokevirtual   #3; //Method EnumClass.ordinal:()I    7:   iaload    8:   lookupswitch{ //2                 1: 36;                 2: 39;                 default: 42 }    36:  ldc     #4; //String value 1    38:  areturn    39:  ldc     #5; //String value 3    41:  areturn    42:  ldc     #6; //String other    44:  areturn 

tableswitch is used if there are three or more switch cases as it performs a more efficient constant-time lookup vs. lookupswitch's linear search. Technically speaking javac could omit this whole business with the synthetic switch map when it uses lookupswitch.

Speculation: I don't have Eclipse's compiler on hand to test with but I imagine that it doesn't bother with a synthetic class and simply uses lookupswitch. Or perhaps it requires more switch cases than the original asker tested with before it "ugprades" to tableswitch.

like image 141
John Kugelman Avatar answered Sep 24 '22 15:09

John Kugelman