6

私は大量の生成された定数を保持するクラスを持っています:

public class Constants extends SomeBaseClass {

  // init() is defined in some base class...
  public static final XXX KEY1 = init(...);
  public static final XXX KEY2 = init(...);
  public static final XXX KEY3 = init(...);

  // ...
  public static final XXX KEY2000 = init(...);
}

生成された定数の数が非常に多い場合、静的初期化子が Java メソッド サイズの上限 (つまり > 64kb) よりも大きくなり、コンパイラ エラーが発生します。1 つの解決策は、メソッドに適合するように、64kb 未満のバイトコードを生成することが保証されているブロックに対して、いくつかの「ブロック初期化メソッド」を作成することです。

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 final私の質問は、定数を生成できる方法でそのコンパイラ/JVM の制限を回避するにはどうすればよいですか?

4

4 に答える 4

7

One option would be to use inheritance - have a series of classes Constants1, Constants2, ..., ConstantsN that all define the constants, then have each one inherit from the previous one. The final class Constants can then directly inherit from the last of them. This also lets you mark everything final.

Out of curiosity, how did you end up with a file so large that you couldn't fit the initialization code into the 64KB limit?

Hope this helps!

于 2012-05-31T21:49:18.647 に答える
1

私は最終的に、ネストされたクラスを含むソリューションに行きました。これは、ユーザーLoadmasterによるこの回答へのコメントで提案されました。ネストされたクラスには 2 つの利点があります。

  • privateネストされたクラスにすることで、これらの回避策の実装の詳細を外の世界から隠すことができます
  • それらは定数を維持することを可能にしますfinal

ただし、 templatetypedef のソリューションと比較して欠点もあります。

  • はるかに多くの定数を使用して、同じ問題に再び遭遇します

ただし、現時点では、これが最も適切なソリューションのようです。

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 ... {}
}
于 2012-06-03T11:24:36.490 に答える
0

これはうまくいきませんか? 番号。この種の回答で問題が解決しない理由については、コメントを参照してください。

これにより、静的変数を最終的な状態に保つことができ、自動生成が容易になります。 ただし、Java はすべての静的 init ブロックを 1 つの巨大な静的 init ブロックにまとめるため、問題は解決されません。

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(...);
  }

  // ...

}
于 2012-05-31T23:53:04.450 に答える
-1

静的初期化ブロックはいくつでも持つことができます。

于 2012-06-01T00:28:08.737 に答える