Подтвердить что ты не робот

Java: Когда используется статический блок инициализации?

Какая разница между инициализацией внутри блока 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;

    ....
4b9b3361

Ответ 1

Статические блоки инициализации позволяют более сложную инициализацию, например, используя условные обозначения:

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

Или, когда требуется больше, чем просто строительство: при использовании построителя для создания вашего экземпляра необходима обработка исключений или работа, отличная от создания статических полей.

Статический блок инициализации также запускается после встроенных статических инициализаторов, поэтому допустимо следующее:

static double a;
static double b = 1;

static {
    a = b * 4; // Evaluates to 4
}

Ответ 2

Типичное использование:

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

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

Как бы вы это сделали без статического инициализатора?

Ответ 3

Обработка исключений при инициализации - еще одна причина. Например:

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

Это полезно для конструкторов, которые досадно бросают проверенные исключения, например выше, или еще более сложную логику инициализации, которая может быть подвержена исключению.

Ответ 4

Иногда вы хотите сделать больше, чем просто присваивать значения статическим переменным. Поскольку вы не можете помещать произвольные выражения в тело класса, вы можете использовать статический блок инициализатора.

Ответ 5

Вы можете использовать блок try/catch внутри static{}, как показано ниже:

MyCode{

    static Scanner input = new Scanner(System.in);
    static boolean flag = true;
    static int B = input.nextInt();
    static int H = input.nextInt();

    static{
        try{
            if(B <= 0 || H <= 0){
                flag = false;
                throw new Exception("Breadth and height must be positive");
            }
        }catch(Exception e){
            System.out.println(e);
        }

    }
}

PS: по ссылке с этого!

Ответ 6

В вашем примере нет разницы; но часто начальное значение является более сложным, чем удобно выразить в одном выражении (например, a List<String>, содержание которого лучше всего выражается с помощью for -loop, или оно Method, которое может не существовать, поэтому исключение необходимы обработчики) и/или статические поля должны быть установлены в определенном порядке.

Ответ 7

Блок

static может использоваться для инициализации экземпляра singleton, чтобы предотвратить использование синхронизированного getInstance() метода.

Ответ 8

Технически, вы можете уйти без него. Некоторые предпочитают многострочный код инициализации, чтобы перейти в статический метод. Я очень доволен использованием статического инициализатора для относительно простой инициализации многоступенчатых.

Конечно, я почти всегда ставил свою статику final и указывал на немодифицируемый объект.

Ответ 9

Ключевое слово Static (независимо от того, является ли оно переменной или блоком), принадлежит классу. Поэтому, когда класс вызывается, эти переменные или блоки выполняются. Поэтому большая часть инициализации будет выполняться с помощью статического ключевого слова. Поскольку он принадлежит самому классу, класс может напрямую обращаться к нему, не создавая экземпляр класса.

Возьмем пример: существует класс обуви, в котором есть несколько переменных, таких как цвет, размер, бренд и т.д. И вот если обувь производственная компания имеет только одну марку, чем мы должны ее инициализировать как статическая переменная. Итак, когда класс обуви называется и разные типы обуви (путем создания экземпляра класса) на этот цвет времени и размер будут занимать память всякий раз, когда новый ботинок но здесь бренд является общим достоянием для всех туфель, так что он будет занимают память на этот раз независимо от того, сколько обуви изготовлено.

Пример:

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

Ответ 10

Статический блок кода позволяет инициализировать поля с большей степенью, инициализировать поля в другом порядке объявлений, а также может использоваться для условной инициализации.

Более конкретно,

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

не будет работать, потому что a и b объявляются после ab.

Однако я мог бы использовать статический init. блок, чтобы преодолеть это.

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;
}

Ответ 11

Статический блок инициализации полезен, если вы хотите инициализировать указанные классы статических типов перед первым использованием класса. Последующее использование не вызовет какие-либо статические блоки инициализации. Это прямая противоположность инициализаторам экземпляра, которые инициализируют члены экземпляра.

Ответ 12

Мы используем конструкторы для инициализации переменных нашего экземпляра (нестатические переменные, переменные, принадлежащие объектам, а не классу).

Если вы хотите инициализировать переменные класса (статические переменные) и хотите сделать это без создания объекта (конструкторы можно вызывать только при создании объекта), тогда вам нужны статические блоки.

static Scanner input = new Scanner(System.in);
static int widht;
static int height;

static
{
    widht = input.nextInt();
    input.nextLine();
    height = input.nextInt();
    input.close();

    if ((widht < 0) || (height < 0))
    {
        System.out.println("java.lang.Exception: Width and height must be positive");
    }
    else
    {
        System.out.println("widht * height");
    }
}

Ответ 13

Если вы хотите оценить какое-либо определенное выражение во время загрузки класса, вы можете использовать статический блок, но помните:

Вы должны обработать исключение в статическом блоке, то есть вы не можете выбросить исключение из статического блока.