117

staticブロック内の初期化の違いは何ですか:

public class staticTest {

    static String s;
    static int n;
    static double d;

    static {
        s = "I'm static";
        n = 500;
        d = 4000.0001;
    }
    ...

そして個々の静的初期化:

public class staticTest {

    static String s = "I'm static";
    static int n    = 500;
    static double d = 4000.0001;

    ....
4

13 に答える 13

129

A static initialization blocks allows more complex initialization, for example using conditionals:

static double a;
static {
    if (SomeCondition) {
      a = 0;
    } else {
      a = 1;
    }
}

Or when more than just construction is required: when using a builder to create your instance, exception handling or work other than creating static fields is necessary.

A static initialization block also runs after the inline static initializers, so the following is valid:

static double a;
static double b = 1;

static {
    a = b * 4; // Evaluates to 4
}
于 2012-02-21T14:41:26.270 に答える
19

典型的な使用法:

private final static Set<String> SET = new HashSet<String>();

static {
    SET.add("value1");
    SET.add("value2");
    SET.add("value3");
}

静的初期化子なしでどのようにしますか?

于 2012-02-21T14:45:15.803 に答える
12

初期化中の例外処理も別の理由です。例えば:

static URL url;
static {
    try {
        url = new URL("https://blahblah.com");
    }
    catch (MalformedURLException mue) {
        //log exception or handle otherwise
    }
}

これは、上記のように面倒なチェック例外をスローするコンストラクターや、例外が発生しやすい可能性のあるより複雑な初期化ロジックに役立ちます。

于 2012-02-21T14:47:36.287 に答える
5

Sometimes you want to do more than just assign values to static variables. Since you cannot put arbitrary statements in the class body, you could use a static initializer block.

于 2012-02-21T14:41:23.133 に答える
4

staticブロックを使用してシングルトンインスタンスを初期化し、同期 getInstance()メソッドの使用を防ぐことができます。

于 2012-02-22T08:35:40.337 に答える
4

あなたの例では、違いはありません。しかし、多くの場合、初期値は 1 つの式で快適に表現するよりも複雑です (たとえば、List<String>その内容をループで表現するのが最適なforです。または、Method存在しない可能性のある であるため、例外ハンドラが必要です)、および/または静的フィールドは特定の順序で設定する必要があります。

于 2012-02-21T14:40:57.880 に答える
3

static キーワード (変数かブロックかに関係なく) はクラスに属します。したがって、クラスが呼び出されると、これらの変数またはブロックが実行されます。そのため、ほとんどの初期化は static キーワードを使用して行われます。クラス自体に属しているため、クラスのインスタンスを作成せずに、クラスから直接アクセスできます。

例を見てみましょう。色、サイズ、ブランドなどのいくつかの変数がある靴のクラスがあります。ここで、靴製造会社が 1 つのブランドしか持っていない場合は、それを静的変数として初期化する必要があります。そのため、靴のクラスが呼び出され、(クラスのインスタンスを作成することによって) さまざまな種類の靴が製造されると、その時点で新しい靴が作成されるたびに色とサイズがメモリを占有しますが、ここではブランドはすべての靴に共通のプロパティです。靴がいくつ製造されても、一度だけメモリを占有するようにします。

例:

    class Shoe {
    int size;
    String colour;
    static String brand = "Nike";

    public Shoe(int size, String colour) {
        super();
        this.size = size;
        this.colour = colour;
    }

    void displayShoe() {
        System.out.printf("%-2d %-8s %s %n",size,colour, brand);
    }

    public static void main(String args[]) {
        Shoe s1 = new Shoe(7, "Blue");
        Shoe s2 = new Shoe(8, "White");

        System.out.println("=================");
        s1.displayShoe();
        s2.displayShoe();
        System.out.println("=================");
    }
}
于 2016-08-24T12:09:52.080 に答える
3

Technically, you could get away without it. Some prefer multiline initialisation code to go into a static method. I'm quite happy using a static initialiser for relatively simple multistatement initialisation.

Of course, I'd almost always make my statics final and point to an unmodifiable object.

于 2012-02-21T14:42:14.300 に答える
1

静的コード ブロックを使用すると、複数の命令でフィールドを初期化したり、宣言の異なる順序でフィールドを初期化したり、条件付き初期化にも使用できます。

すなわち、

static final String ab = a+b;
static final String a = "Hello,";
static final String b = ", world";

ab の後に a と b が宣言されているため、動作しません。

ただし、静的初期化を使用できます。これを克服するためにブロックします。

static final String ab;
static final String a;
static final String b;

static {
  b = ", world";
  a = "Hello";
  ab = a + b;
}

static final String ab;
static final String a;
static final String b;

static {
  b = (...) ? ", world" : ", universe";
  a = "Hello";
  ab = a + b;
}
于 2012-02-21T14:46:32.880 に答える