Этот пост является продолжением изучения малоизвестных возможностей Java. В предыдущем посте я рассмотрел несколько весьма неожиданных случаев использования класса sun.misc.Unsafe. В этом посте я обсуждаю малоизвестную возможность блоков инициализаторов.
1. Блоки инициализатора
Блок инициализации — это блок кода между фигурными скобками, который выполняется до создания экземпляра класса и даже до вызова конструкторов. Вовсе не обязательно включать их в свои классы.
Инициализаторы можно использовать двумя способами:
- Блок инициализации экземпляра: он зависит от объекта, и блок инициализации выполняется для каждого объекта класса, который создается. Он может инициализировать переменные-члены экземпляра класса.
- Статический блок инициализатора: он определяется с помощью ключевого слова static и выполняется один раз при загрузке класса, а также имеет ограничение, заключающееся в том, что он может инициализировать только статические члены данных класса.
Это то, что мы все знаем. Теперь перейдем к той части, которую многие из нас не знали раньше.
2. Блоки инициализатора могут вызывать исключения
Иногда в блоке инициализатора вам может понадобиться написать некоторый код, который может выдавать проверенные исключения. Проверенные исключения — это те исключения, которые проверяются во время компиляции, и компилятор заставляет вас обрабатывать их в вашем коде. Давайте рассмотрим пример:
public class CheckedExceptionsFromConstrctor {Document doc = null;{doc = new SAXBuilder(false).build(new StringReader(new String("<users>")));}}
Приведенный выше код выдает два проверенных исключения: IOException и JDOMException. Мы можем обработать их с помощью try-catch. Например
public class CheckedExceptionsFromConstrctor {Document doc = null;try {doc = new SAXBuilder(false).build(new StringReader(new String("<users>")));} catch(JDOMException | IOException e) {e.printStackTrace();}}
Если вы не хотите обрабатывать исключения в инициализаторе и пытаетесь их сгенерировать, компилятор не позволит вам этого сделать.
public class CheckedExceptionsFromConstrctor {Document doc = null;try {doc = new SAXBuilder(false).build(new StringReader(new String("<users>")));} catch(JDOMException | IOException e) {throw e; //Not allowed}}
3. Объявление исключений из инициализаторов экземпляров в конструкторе
Добавьте предложение throws в конструкторы, и вы сможете выбрасывать проверяемые исключения из инициализаторов. Например:
public class CheckedExceptionsFromConstrctor {Document doc = null;public CheckedExceptionsFromConstrctor() throws IOException, JDOMException {//constructor}{doc = new SAXBuilder(false).build(new StringReader(new String("<users>")));}}
4. Статические инициализаторы не могут вызывать проверяемые исключения.
Приведенное выше обоснование было для нестатических или инициализаторов экземпляров. Если в вашем классе есть статические инициализаторы, то вы ДОЛЖНЫ обрабатывать проверяемые исключения. Вам не разрешено выбрасывать их любым возможным способом.
public class CheckedExceptionsFromConstrctor{static Document doc = null;public CheckedExceptionsFromConstrctor() {//Some other code}static {try {doc = new SAXBuilder(false).build(new StringReader(new String("<users>")));} catch(JDOMException | IOException e) {e.printStackTrace(); //You must handle the exception here}}}
Вот и все по этой теме. Надеюсь, вам понравилось. Буду признателен, если вы поделитесь своими мыслями в комментариях. И не забудьте подписаться по электронной почте, чтобы получать новые обновления по таким малоизвестным функциям.