2016-07-27 2 views
-3

클래스, 열거 형, 테스트를 통해 이러한 3 가지 방법으로 상수 String을 캡슐화합니다.Java Enum이 인터페이스보다 많은 메모리를 사용하는 이유는 무엇입니까?

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 
    } 

컴파일 후에, 그들은 JVM으로로드 될 때 더 적은 메모리 비용 인터페이스 ICompany 수단 바이트를 330 바이트, 181 바이트 및 818 바이트를 생성. 왜 이런거야?

+3

그 (것)들은 동등한 자료 구조가 아니기 때문에 아마? –

+1

인터페이스에는 필드 이름, 유형 및 값이 있어야합니다. enum은 상수 값 외에도 여러 가지 메소드 구현 ('values ​​()'및'valueOf (String)'및 정적 초기화)을 저장해야합니다. – resueman

답변

2

javap 유틸리티를 사용하여 3 개의 ".class"파일을 검사하고 출력을 비교하십시오. 예를 들어 :

$ javap -c Company.class 

짧은 대답은 몇 가지 표준 방법 (values(), valueOf(String), toString())는 enum 클래스가 구현해야하는 것이있다, 그러나 다른 클래스는 필요가 없습니다. 그런데 ".class"파일의 크기가 반드시 클래스가로드되고 JIT 컴파일 될 때 사용 된 메모리의 정확한 예측자인 것은 아닙니다.

0

단일 클래스 파일은 클래스 또는 인터페이스를 정의합니다. 구조 (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]; 
    } 

열거 클래스, 그리고 당신이 그것을로 컴파일 어떻게 보면 필요한 오버 헤드가 왜, 당신이 볼 수있는 (여기 참조 : In java, What does such enum type compile 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�� 

, 당신은 예제의 인터페이스는 많은 측면에서 추가하지 않는 것을 볼 수 있습니다 메서드 또는 플래그, 따라서 작은 크기.