6

내가 같은 생성 된 상수의 큰 마운트를 들고 클래스가 자바에서 정적 initialiser의 크기 제한을 회피하기 매우 높으면 Java 메소드 크기의 상한보다 큰 정적 초기화 기 (예 :> 64kb)가 발생하여 컴파일러 오류가 발생합니다. 하나 개의 솔루션들이하는 방법에 적합하도록 바이트 코드의 64킬로바이트보다 적은 생산을 보장 할 수 블록에 대한 몇 가지 "블록 초기화 방법"을 만드는 것입니다 :어떻게

public class Constants extends SomeBaseClass { 

    public static XXX KEY1; 
    public static XXX KEY2; 
    public static XXX KEY3; 

    // ... 
    public static XXX KEY2000; 

    static { 
    initialise0001To1000(); 
    initialise1001To2000(); 
    } 

    private static void initialise0001To1000() { 
    KEY1 = init(...); 
    KEY2 = init(...); 
    KEY3 = init(...); 
    // ... 
    } 

    private static void initialise1001To2000() { 
    // ... 
    KEY2000 = init(...); 
    } 
} 

이것의 단점은 내가 할 수있는 것입니다 final으로 더 이상 선언하지 않습니다. 더 이상 static initialiser에서 더 이상 초기화되지 않기 때문입니다.

제 질문은 어떻게하면 static final 상수를 생성 할 수있는 방법으로 해당 컴파일러/JVM 제한을 우회 할 수 있습니까?

+0

? 이 코드가 다른 파일에서 자동 생성 되었습니까? – templatetypedef

+0

@templatetypedef : 이것은 [jOOQ] (http://www.jooq.org)의 소스 코드 생성기에있는 실제 버그입니다. 기본 키, 고유 키 및 외래 키를 데이터베이스에서 상수 개체로 생성합니다. jOOQ가 처리 할 수있는 2000 개의 키가 너무 많습니다. https://groups.google.com/d/topic/jooq-user/2g96fI1Yrj8/discussion –

+0

"더미"상속 레이어를 사용할 수 있습니까? 1,000 개의 상수를 포함하고 static initializer가 설정된 비공개 사용 이름을 가진 기본 클래스를 만듭니다. 그런 다음 1,000 개를 더한 파생 클래스, 1,000 개를 추가하는 하위 클래스 등이 있습니까? 가장 많이 파생 된 클래스 만 어셈블리의 다른 클래스의 파생을 제외하고는 어떤 목적 으로든 사용됩니다. – supercat

답변

1

마지막으로 중첩 된 클래스가 포함 된 솔루션을 찾았습니다. 이것은 사용자 Loadmaster에 의해 this answer here에 대한 의견에서 제안되었습니다.중첩 된 클래스는 두 가지 장점이 있습니다

그들은 private 중첩 된 클래스 그들은 유지 상수 final

그러나 그들은 또한 단점이 허용

  • 에게 됨으로써 외부에서 이러한 해결 방법의 구현 세부 사항을 숨기는 허용
    • templatetypedef's 솔루션에 비해 :

      • 나는 많은 lar 상수 현재

    • 의 게르 번호는하지만, 이것은 가장 적합한 솔루션이 될 것 같다 :

      public class Constants { 
      
          public static XXX KEY1 = Constants1.KEY1; 
          public static XXX KEY2 = Constants1.KEY2; 
          public static XXX KEY3 = Constants1.KEY3; 
      
          // ... 
          public static XXX KEY2000 = Constants2.KEY2000; 
      
          // Nested class holding 1000 constants 
          private static class Constants1 extends SomeBaseClass { 
          KEY1 = init(...); 
          KEY2 = init(...); 
          KEY3 = init(...); 
          // ... 
          } 
      
          // Nested class holding the next 1000 constants 
          private static class Constants2 extends SomeBaseClass { 
          // ... 
          KEY2000 = init(...); 
          } 
      
          // Keep generating nested classes for more constants... 
          private static class Constants3 ... {} 
      } 
      
      이 문제로 실행 결국 않았다 어떻게
  • 7

    하나의 옵션은 상속을 사용하는 것입니다 - 클래스 Constants1, Constants2의 시리즈가 ..., 모두가 상수를 정의 ConstantsN 후 이전에서 각각 상속 있습니다. 마지막 클래스 Constants은 마지막 것부터 직접 상속받을 수 있습니다. 또한 모든 것을 표시 할 수 있습니다 final.

    호기심에서 벗어나서 초기화 코드를 64KB 제한에 맞출 수 없을 정도로 커진 파일을 어떻게 만들었습니까?

    희망이 도움이됩니다.

    +0

    흠, 그래, 그게 유효한 해결 방법, 좋은 생각이 될 것입니다. 나는 또한 모든 상수를 인터페이스에 넣을 수 있고 상수가 그것들 모두를 구현하도록 할 수 있습니다 ... –

    +0

    추가 된 질문에 대한 대답은 주석에 있습니다 ... –

    +1

    중첩 된 클래스로도이 작업을 수행 할 수 있습니다. 모든 것을 단일 소스 파일에 넣을 수 있습니다. –

    0

    이 기능을 사용하지 않습니까? NO. 이런 종류의 대답으로 문제가 해결되지 않는 이유에 대한 의견을보십시오.

    정적 변수를 마지막으로 유지하면 자동 생성이 더 쉬울 것입니다. 그러나 java는 모든 정적 초기화 블록을 하나의 거대한 정적 초기화 블록으로 축소하므로 문제가 해결되지 않습니다.

    public class Constants extends SomeBaseClass { 
    
        // init() is defined in some base class... 
        public static final XXX KEY1 ; 
        static 
        { 
         KEY1 = init(...); 
        } 
        public static final XXX KEY2 ; 
        static 
        { 
         KEY2 = init(...); 
        } 
        public static final XXX KEY3 ; 
        static 
        { 
         KEY3 = init(...); 
        } 
    
        // ... 
    
    } 
    
    +0

    이미 그와 같은 대답이있었습니다 (즉, 삭제되었습니다). 바이트 코드 클래스에는 하나의 정적 초기화 프로그램 만있는 것으로 보입니다. 컴파일러는 모든 초기화 문을 하나의 문으로 결합합니다. 나는 생각합니다. –

    +0

    그건 수치입니다. 열거 형을 사용하면 똑같은 일이 일어날까요? 단점 XXX는 동일한 클래스 여야하며 init()이 열거 형 생성자를 호출하도록 코드를 다시 작성해야합니다. – emory

    +0

    열거 형을 사용할 수 없습니다. 실세계 타입'XXX'는 제네릭 타입 매개 변수를 가지고 있습니다. : - /하지만 두포에서 열거 형 클래스가 일반 정적 클래스와 동일한 정적 이니셜 라이저 로직을 공유한다고 생각합니다 ... –

    -1

    원하는만큼 정적 초기화 블록을 가질 수 있습니다.

    +0

    그 [emory의] (http://stackoverflow.com/a/10842759/521799) 답변과 동일 ... –