Использование статического блока инициализации

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

7 ответов

Решение

Когда вы хотите инициализировать одну или несколько статических переменных в одном месте

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

Например:

public static ImageIcon defaultIcon = ImageIO.read(..);

можно инициализировать с помощью

public static ImageIcon defaultIcon;
static {
   try {
       defaultIcon = ImageIO.read(..);
   } catch (IOException ex){
     System.out.println("No default icon available");
   }
}

Другое приложение - сложная инициализация. Например, если элемент требует более одной строки кода для инициализации. Допустим, у вас есть конфигурация:

public static Configuration configuration;
static {
     confuguration = new Configuration();
     configuration.setSomething(..);
     configuration.setSomethingElse(..);
     ...
}

Третье использование - инициализация некоторой внешней инфраструктуры API. Один пример из моего текущего проекта:

static {
    org.apache.xml.security.Init.init();
}

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

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

Я буду ссылаться на @Bozho для примеров.

Не делай

public static Configuration configuration;
static {
     confuguration = new Configuration();
     configuration.setSomething(..);
     configuration.setSomethingElse(..);
     ...
}

Используйте вместо

public static Configuration configuration = createConfiguration();

или же

public static Configuration configuration = YourConfiguration.create();

Они часто используются в сочетании с кодом JNI для обеспечения загрузки необходимой собственной библиотеки:

class MyJniConnection {

    public static native void myJniCall();

    static {
        System.load("native.dll");
    }
}
  • Инициализация статического поля коллекции, например Map, List, Set и т. Д.
  • Инициализация объекта на основе сеттера, который также является статическим

Драйвер JDBC является популярным примером

Зачем тебе Class.forName() загрузить драйвер в память. Ответ прост. Как указано в спецификации JDBC, все JDBC Driver иметь статический блок для регистрации DriverManager как только Driver класс загружен. Что-то вроде этого:

static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
        throw new RuntimeException("Can't register driver!");
    }
}

Итак, когда вы пишете (например, с драйвером MySQL здесь):

Class.forName("org.gjt.mm.mysql.Driver");

Загрузчик классов пытается загрузить и связать org.gjt.mm.mysql.Driver класс и, в случае успеха, выполняется статический блок инициализации и Driver регистрируется с DriverManager,

Их можно использовать для создания DSL, как это делает JMock. Например, чтобы установить ожидание того, что пользователь будет сохранен в базе данных:

Mockery context = new Mockery();
final Database database = context.mock(Database.class);    
...
context.checking(new Expectations() {{
    oneOf(database).save(user);
}});

// Rest of the test
  • статический блок:- когда мы хотим выполнить код во время загрузки класса, тогда мы можем поместить код в статический блок...
  • init:- когда мы хотим выполнить код во время инициализации объекта класса, тогда мы можем поместить код в блок init....
Другие вопросы по тегам